about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNicholas Nethercote <nnethercote@mozilla.com>2019-05-08 13:21:18 +1000
committerNicholas Nethercote <nnethercote@mozilla.com>2019-05-13 09:29:22 +1000
commitfb084a48e2ca663de41b316dc6ece2dceb93e24e (patch)
treeb78379f996dceee6039ea4880c66e7fe30b3efad
parent79602c87b561e26fa1a8fe58b9130cca37375f90 (diff)
downloadrust-fb084a48e2ca663de41b316dc6ece2dceb93e24e.tar.gz
rust-fb084a48e2ca663de41b316dc6ece2dceb93e24e.zip
Pass a `Symbol` to `check_name`, `emit_feature_err`, and related functions.
-rw-r--r--src/librustc/hir/check_attr.rs21
-rw-r--r--src/librustc/hir/lowering.rs10
-rw-r--r--src/librustc/ich/hcx.rs2
-rw-r--r--src/librustc/ich/mod.rs20
-rw-r--r--src/librustc/lint/levels.rs4
-rw-r--r--src/librustc/middle/dead.rs9
-rw-r--r--src/librustc/middle/entry.rs7
-rw-r--r--src/librustc/middle/lang_items.rs8
-rw-r--r--src/librustc/middle/liveness.rs4
-rw-r--r--src/librustc/middle/mem_categorization.rs3
-rw-r--r--src/librustc/middle/recursion_limit.rs7
-rw-r--r--src/librustc/middle/resolve_lifetime.rs4
-rw-r--r--src/librustc/middle/stability.rs10
-rw-r--r--src/librustc/query/mod.rs2
-rw-r--r--src/librustc/session/mod.rs3
-rw-r--r--src/librustc/traits/coherence.rs9
-rw-r--r--src/librustc/traits/error_reporting.rs3
-rw-r--r--src/librustc/traits/on_unimplemented.rs11
-rw-r--r--src/librustc/ty/context.rs9
-rw-r--r--src/librustc/ty/mod.rs12
-rw-r--r--src/librustc/ty/util.rs3
-rw-r--r--src/librustc_allocator/expand.rs4
-rw-r--r--src/librustc_codegen_llvm/attributes.rs4
-rw-r--r--src/librustc_codegen_llvm/consts.rs3
-rw-r--r--src/librustc_codegen_llvm/debuginfo/gdb.rs4
-rw-r--r--src/librustc_codegen_llvm/llvm_util.rs135
-rw-r--r--src/librustc_codegen_ssa/back/write.rs6
-rw-r--r--src/librustc_codegen_ssa/mir/rvalue.rs6
-rw-r--r--src/librustc_codegen_utils/lib.rs3
-rw-r--r--src/librustc_codegen_utils/link.rs3
-rw-r--r--src/librustc_codegen_utils/symbol_names_test.rs6
-rw-r--r--src/librustc_incremental/assert_module_sources.rs9
-rw-r--r--src/librustc_incremental/persist/dirty_clean.rs13
-rw-r--r--src/librustc_interface/passes.rs2
-rw-r--r--src/librustc_interface/proc_macro_decls.rs3
-rw-r--r--src/librustc_interface/util.rs4
-rw-r--r--src/librustc_lint/builtin.rs22
-rw-r--r--src/librustc_lint/nonstandard_style.rs7
-rw-r--r--src/librustc_lint/unused.rs8
-rw-r--r--src/librustc_metadata/creader.rs12
-rw-r--r--src/librustc_metadata/decoder.rs4
-rw-r--r--src/librustc_metadata/encoder.rs18
-rw-r--r--src/librustc_metadata/link_args.rs3
-rw-r--r--src/librustc_metadata/native_libs.rs16
-rw-r--r--src/librustc_mir/borrow_check/error_reporting.rs3
-rw-r--r--src/librustc_mir/borrow_check/nll/mod.rs3
-rw-r--r--src/librustc_mir/dataflow/mod.rs11
-rw-r--r--src/librustc_mir/hair/cx/mod.rs4
-rw-r--r--src/librustc_mir/hair/pattern/mod.rs5
-rw-r--r--src/librustc_mir/interpret/cast.rs6
-rw-r--r--src/librustc_mir/transform/check_unsafety.rs4
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs25
-rw-r--r--src/librustc_mir/transform/rustc_peek.rs11
-rw-r--r--src/librustc_passes/ast_validation.rs8
-rw-r--r--src/librustc_passes/layout_test.rs3
-rw-r--r--src/librustc_passes/rvalue_promotion.rs3
-rw-r--r--src/librustc_plugin/build.rs4
-rw-r--r--src/librustc_plugin/load.rs3
-rw-r--r--src/librustc_plugin/registry.rs4
-rw-r--r--src/librustc_privacy/lib.rs7
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs22
-rw-r--r--src/librustc_resolve/lib.rs8
-rw-r--r--src/librustc_resolve/macros.rs15
-rw-r--r--src/librustc_save_analysis/lib.rs6
-rw-r--r--src/librustc_traits/lowering/mod.rs5
-rw-r--r--src/librustc_typeck/astconv.rs3
-rw-r--r--src/librustc_typeck/check/coercion.rs3
-rw-r--r--src/librustc_typeck/check/demand.rs3
-rw-r--r--src/librustc_typeck/check/mod.rs8
-rw-r--r--src/librustc_typeck/check/wfcheck.rs3
-rw-r--r--src/librustc_typeck/check/writeback.rs5
-rw-r--r--src/librustc_typeck/collect.rs84
-rw-r--r--src/librustc_typeck/outlives/mod.rs3
-rw-r--r--src/librustc_typeck/outlives/test.rs3
-rw-r--r--src/librustc_typeck/variance/test.rs3
-rw-r--r--src/librustdoc/clean/inline.rs3
-rw-r--r--src/librustdoc/clean/mod.rs59
-rw-r--r--src/librustdoc/core.rs3
-rw-r--r--src/librustdoc/html/render.rs11
-rw-r--r--src/librustdoc/passes/calculate_doc_coverage.rs3
-rw-r--r--src/librustdoc/passes/collect_trait_impls.rs5
-rw-r--r--src/librustdoc/passes/strip_hidden.rs3
-rw-r--r--src/librustdoc/test.rs16
-rw-r--r--src/librustdoc/visit_ast.rs26
-rw-r--r--src/librustdoc/visit_lib.rs3
-rw-r--r--src/libsyntax/attr/builtin.rs18
-rw-r--r--src/libsyntax/attr/mod.rs25
-rw-r--r--src/libsyntax/config.rs11
-rw-r--r--src/libsyntax/entry.rs5
-rw-r--r--src/libsyntax/ext/expand.rs30
-rw-r--r--src/libsyntax/ext/source_util.rs4
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs12
-rw-r--r--src/libsyntax/feature_gate.rs191
-rw-r--r--src/libsyntax/parse/mod.rs6
-rw-r--r--src/libsyntax/parse/parser.rs6
-rw-r--r--src/libsyntax/std_inject.rs8
-rw-r--r--src/libsyntax/test.rs11
-rw-r--r--src/libsyntax_ext/asm.rs4
-rw-r--r--src/libsyntax_ext/concat_idents.rs4
-rw-r--r--src/libsyntax_ext/deriving/clone.rs4
-rw-r--r--src/libsyntax_ext/deriving/generic/mod.rs4
-rw-r--r--src/libsyntax_ext/format.rs6
-rw-r--r--src/libsyntax_ext/global_asm.rs4
-rw-r--r--src/libsyntax_ext/log_syntax.rs3
-rw-r--r--src/libsyntax_ext/proc_macro_decls.rs18
-rw-r--r--src/libsyntax_ext/test.rs12
-rw-r--r--src/libsyntax_ext/test_case.rs4
-rw-r--r--src/libsyntax_ext/trace_macros.rs4
-rw-r--r--src/libsyntax_pos/lib.rs4
-rw-r--r--src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin-attr.rs4
-rw-r--r--src/test/run-pass-fulldeps/auxiliary/issue-40001-plugin.rs4
-rw-r--r--src/test/run-pass-fulldeps/auxiliary/lint-for-crate.rs7
-rw-r--r--src/test/ui-fulldeps/auxiliary/attr-plugin-test.rs8
-rw-r--r--src/test/ui-fulldeps/auxiliary/lint-for-crate.rs3
114 files changed, 670 insertions, 620 deletions
diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs
index 4c527f80d0f..23c8a671ec5 100644
--- a/src/librustc/hir/check_attr.rs
+++ b/src/librustc/hir/check_attr.rs
@@ -12,6 +12,7 @@ use crate::hir;
 use crate::hir::def_id::DefId;
 use crate::hir::intravisit::{self, Visitor, NestedVisitorMap};
 use std::fmt::{self, Display};
+use syntax::symbol::sym;
 use syntax_pos::Span;
 
 #[derive(Copy, Clone, PartialEq)]
@@ -95,18 +96,18 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
     fn check_attributes(&self, item: &hir::Item, target: Target) {
         if target == Target::Fn || target == Target::Const {
             self.tcx.codegen_fn_attrs(self.tcx.hir().local_def_id_from_hir_id(item.hir_id));
-        } else if let Some(a) = item.attrs.iter().find(|a| a.check_name("target_feature")) {
+        } else if let Some(a) = item.attrs.iter().find(|a| a.check_name(sym::target_feature)) {
             self.tcx.sess.struct_span_err(a.span, "attribute should be applied to a function")
                 .span_label(item.span, "not a function")
                 .emit();
         }
 
         for attr in &item.attrs {
-            if attr.check_name("inline") {
+            if attr.check_name(sym::inline) {
                 self.check_inline(attr, &item.span, target)
-            } else if attr.check_name("non_exhaustive") {
+            } else if attr.check_name(sym::non_exhaustive) {
                 self.check_non_exhaustive(attr, item, target)
-            } else if attr.check_name("marker") {
+            } else if attr.check_name(sym::marker) {
                 self.check_marker(attr, item, target)
             }
         }
@@ -166,7 +167,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
         // ```
         let hints: Vec<_> = item.attrs
             .iter()
-            .filter(|attr| attr.check_name("repr"))
+            .filter(|attr| attr.check_name(sym::repr))
             .filter_map(|attr| attr.meta_item_list())
             .flatten()
             .collect();
@@ -268,10 +269,10 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
         // When checking statements ignore expressions, they will be checked later
         if let hir::StmtKind::Local(ref l) = stmt.node {
             for attr in l.attrs.iter() {
-                if attr.check_name("inline") {
+                if attr.check_name(sym::inline) {
                     self.check_inline(attr, &stmt.span, Target::Statement);
                 }
-                if attr.check_name("repr") {
+                if attr.check_name(sym::repr) {
                     self.emit_repr_error(
                         attr.span,
                         stmt.span,
@@ -289,10 +290,10 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
             _ => Target::Expression,
         };
         for attr in expr.attrs.iter() {
-            if attr.check_name("inline") {
+            if attr.check_name(sym::inline) {
                 self.check_inline(attr, &expr.span, target);
             }
-            if attr.check_name("repr") {
+            if attr.check_name(sym::repr) {
                 self.emit_repr_error(
                     attr.span,
                     expr.span,
@@ -305,7 +306,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
 
     fn check_used(&self, item: &hir::Item, target: Target) {
         for attr in &item.attrs {
-            if attr.check_name("used") && target != Target::Static {
+            if attr.check_name(sym::used) && target != Target::Static {
                 self.tcx.sess
                     .span_err(attr.span, "attribute must be applied to a `static` variable");
             }
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 5b334b24e2f..0d80a0874e6 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -64,7 +64,7 @@ use syntax::ptr::P;
 use syntax::source_map::{respan, CompilerDesugaringKind, Spanned};
 use syntax::source_map::CompilerDesugaringKind::IfTemporary;
 use syntax::std_inject;
-use syntax::symbol::{keywords, Symbol};
+use syntax::symbol::{keywords, Symbol, sym};
 use syntax::tokenstream::{TokenStream, TokenTree};
 use syntax::parse::token::Token;
 use syntax::visit::{self, Visitor};
@@ -2727,7 +2727,7 @@ impl<'a> LoweringContext<'a> {
                         self.lower_ty(x, ImplTraitContext::disallowed())
                     }),
                     synthetic: param.attrs.iter()
-                                          .filter(|attr| attr.check_name("rustc_synthetic"))
+                                          .filter(|attr| attr.check_name(sym::rustc_synthetic))
                                           .map(|_| hir::SyntheticTyParamKind::ImplTrait)
                                           .next(),
                 };
@@ -2745,7 +2745,7 @@ impl<'a> LoweringContext<'a> {
             hir_id: self.lower_node_id(param.id),
             name,
             span: param.ident.span,
-            pure_wrt_drop: attr::contains_name(&param.attrs, "may_dangle"),
+            pure_wrt_drop: attr::contains_name(&param.attrs, sym::may_dangle),
             attrs: self.lower_attrs(&param.attrs),
             bounds,
             kind,
@@ -3773,8 +3773,8 @@ impl<'a> LoweringContext<'a> {
         let mut vis = self.lower_visibility(&i.vis, None);
         let attrs = self.lower_attrs(&i.attrs);
         if let ItemKind::MacroDef(ref def) = i.node {
-            if !def.legacy || attr::contains_name(&i.attrs, "macro_export") ||
-                              attr::contains_name(&i.attrs, "rustc_doc_only_macro") {
+            if !def.legacy || attr::contains_name(&i.attrs, sym::macro_export) ||
+                              attr::contains_name(&i.attrs, sym::rustc_doc_only_macro) {
                 let body = self.lower_token_stream(def.stream());
                 let hir_id = self.lower_node_id(i.id);
                 self.exported_macros.push(hir::MacroDef {
diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs
index 6da2cb9ab57..8be610e8bf7 100644
--- a/src/librustc/ich/hcx.rs
+++ b/src/librustc/ich/hcx.rs
@@ -28,7 +28,7 @@ use smallvec::SmallVec;
 
 fn compute_ignored_attr_names() -> FxHashSet<Symbol> {
     debug_assert!(ich::IGNORED_ATTRIBUTES.len() > 0);
-    ich::IGNORED_ATTRIBUTES.iter().map(|&s| Symbol::intern(s)).collect()
+    ich::IGNORED_ATTRIBUTES.iter().map(|&s| s).collect()
 }
 
 /// This is the context state available during incr. comp. hashing. It contains
diff --git a/src/librustc/ich/mod.rs b/src/librustc/ich/mod.rs
index b407b75e68c..f3fc7ec8fda 100644
--- a/src/librustc/ich/mod.rs
+++ b/src/librustc/ich/mod.rs
@@ -4,6 +4,8 @@ crate use rustc_data_structures::fingerprint::Fingerprint;
 pub use self::caching_source_map_view::CachingSourceMapView;
 pub use self::hcx::{StableHashingContextProvider, StableHashingContext, NodeIdHashingMode,
                     hash_stable_trait_impls};
+use syntax::symbol::{Symbol, sym};
+
 mod caching_source_map_view;
 mod hcx;
 
@@ -12,16 +14,16 @@ mod impls_misc;
 mod impls_ty;
 mod impls_syntax;
 
-pub const ATTR_DIRTY: &str = "rustc_dirty";
-pub const ATTR_CLEAN: &str = "rustc_clean";
-pub const ATTR_IF_THIS_CHANGED: &str = "rustc_if_this_changed";
-pub const ATTR_THEN_THIS_WOULD_NEED: &str = "rustc_then_this_would_need";
-pub const ATTR_PARTITION_REUSED: &str = "rustc_partition_reused";
-pub const ATTR_PARTITION_CODEGENED: &str = "rustc_partition_codegened";
-pub const ATTR_EXPECTED_CGU_REUSE: &str = "rustc_expected_cgu_reuse";
+pub const ATTR_DIRTY: Symbol = sym::rustc_dirty;
+pub const ATTR_CLEAN: Symbol = sym::rustc_clean;
+pub const ATTR_IF_THIS_CHANGED: Symbol = sym::rustc_if_this_changed;
+pub const ATTR_THEN_THIS_WOULD_NEED: Symbol = sym::rustc_then_this_would_need;
+pub const ATTR_PARTITION_REUSED: Symbol = sym::rustc_partition_reused;
+pub const ATTR_PARTITION_CODEGENED: Symbol = sym::rustc_partition_codegened;
+pub const ATTR_EXPECTED_CGU_REUSE: Symbol = sym::rustc_expected_cgu_reuse;
 
-pub const IGNORED_ATTRIBUTES: &[&str] = &[
-    "cfg",
+pub const IGNORED_ATTRIBUTES: &[Symbol] = &[
+    sym::cfg,
     ATTR_IF_THIS_CHANGED,
     ATTR_THEN_THIS_WOULD_NEED,
     ATTR_DIRTY,
diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs
index 2e5bd8add0c..a69758e33ba 100644
--- a/src/librustc/lint/levels.rs
+++ b/src/librustc/lint/levels.rs
@@ -14,7 +14,7 @@ use syntax::ast;
 use syntax::attr;
 use syntax::feature_gate;
 use syntax::source_map::MultiSpan;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 
 pub struct LintLevelSets {
     list: Vec<LintSet>,
@@ -230,7 +230,7 @@ impl<'a> LintLevelsBuilder<'a> {
                                 if !self.sess.features_untracked().lint_reasons {
                                     feature_gate::emit_feature_err(
                                         &self.sess.parse_sess,
-                                        "lint_reasons",
+                                        sym::lint_reasons,
                                         item.span,
                                         feature_gate::GateIssue::Language,
                                         "lint reasons are experimental"
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index a0107ed0546..2a9928567f4 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -19,6 +19,7 @@ use rustc_data_structures::fx::FxHashMap;
 
 use syntax::{ast, source_map};
 use syntax::attr;
+use syntax::symbol::sym;
 use syntax_pos;
 
 // Any local node that may call something in its body block should be
@@ -304,22 +305,22 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
 fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt<'_, '_, '_>,
                                     id: hir::HirId,
                                     attrs: &[ast::Attribute]) -> bool {
-    if attr::contains_name(attrs, "lang") {
+    if attr::contains_name(attrs, sym::lang) {
         return true;
     }
 
     // Stable attribute for #[lang = "panic_impl"]
-    if attr::contains_name(attrs, "panic_handler") {
+    if attr::contains_name(attrs, sym::panic_handler) {
         return true;
     }
 
     // (To be) stable attribute for #[lang = "oom"]
-    if attr::contains_name(attrs, "alloc_error_handler") {
+    if attr::contains_name(attrs, sym::alloc_error_handler) {
         return true;
     }
 
     // Don't lint about global allocators
-    if attr::contains_name(attrs, "global_allocator") {
+    if attr::contains_name(attrs, sym::global_allocator) {
         return true;
     }
 
diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs
index df77033ebef..e2e76e69dc4 100644
--- a/src/librustc/middle/entry.rs
+++ b/src/librustc/middle/entry.rs
@@ -4,6 +4,7 @@ use crate::session::{config, Session};
 use crate::session::config::EntryFnType;
 use syntax::attr;
 use syntax::entry::EntryPointType;
+use syntax::symbol::sym;
 use syntax_pos::Span;
 use crate::hir::{HirId, Item, ItemKind, ImplItem, TraitItem};
 use crate::hir::itemlikevisit::ItemLikeVisitor;
@@ -58,7 +59,7 @@ fn entry_fn(tcx: TyCtxt<'_, '_, '_>, cnum: CrateNum) -> Option<(DefId, EntryFnTy
     }
 
     // If the user wants no main function at all, then stop here.
-    if attr::contains_name(&tcx.hir().krate().attrs, "no_main") {
+    if attr::contains_name(&tcx.hir().krate().attrs, sym::no_main) {
         return None;
     }
 
@@ -81,9 +82,9 @@ fn entry_fn(tcx: TyCtxt<'_, '_, '_>, cnum: CrateNum) -> Option<(DefId, EntryFnTy
 fn entry_point_type(item: &Item, at_root: bool) -> EntryPointType {
     match item.node {
         ItemKind::Fn(..) => {
-            if attr::contains_name(&item.attrs, "start") {
+            if attr::contains_name(&item.attrs, sym::start) {
                 EntryPointType::Start
-            } else if attr::contains_name(&item.attrs, "main") {
+            } else if attr::contains_name(&item.attrs, sym::main) {
                 EntryPointType::MainAttr
             } else if item.ident.name == "main" {
                 if at_root {
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 0e283ca6b1c..103580a598f 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -18,7 +18,7 @@ use crate::middle::weak_lang_items;
 use crate::util::nodemap::FxHashMap;
 
 use syntax::ast;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 use syntax_pos::Span;
 use rustc_macros::HashStable;
 use crate::hir::itemlikevisit::ItemLikeVisitor;
@@ -209,9 +209,9 @@ impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> {
 /// are also extracted out when found.
 pub fn extract(attrs: &[ast::Attribute]) -> Option<(Symbol, Span)> {
     attrs.iter().find_map(|attr| Some(match attr {
-        _ if attr.check_name("lang") => (attr.value_str()?, attr.span),
-        _ if attr.check_name("panic_handler") => (Symbol::intern("panic_impl"), attr.span),
-        _ if attr.check_name("alloc_error_handler") => (Symbol::intern("oom"), attr.span),
+        _ 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),
         _ => return None,
     }))
 }
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index a142b220f31..cb333b5b0cb 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -112,7 +112,7 @@ use std::io;
 use std::rc::Rc;
 use syntax::ast::{self, NodeId};
 use syntax::ptr::P;
-use syntax::symbol::keywords;
+use syntax::symbol::{keywords, sym};
 use syntax_pos::Span;
 
 use crate::hir;
@@ -362,7 +362,7 @@ fn visit_fn<'a, 'tcx: 'a>(ir: &mut IrMaps<'a, 'tcx>,
     if let FnKind::Method(..) = fk {
         let parent = ir.tcx.hir().get_parent_item(id);
         if let Some(Node::Item(i)) = ir.tcx.hir().find_by_hir_id(parent) {
-            if i.attrs.iter().any(|a| a.check_name("automatically_derived")) {
+            if i.attrs.iter().any(|a| a.check_name(sym::automatically_derived)) {
                 return;
             }
         }
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 85c7f437903..c7f8cf684e6 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -72,6 +72,7 @@ use crate::hir::{MutImmutable, MutMutable, PatKind};
 use crate::hir::pat_util::EnumerateAndAdjustIterator;
 use crate::hir;
 use syntax::ast::{self, Name};
+use syntax::symbol::sym;
 use syntax_pos::Span;
 
 use std::borrow::Cow;
@@ -714,7 +715,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
                 // they also cannot be moved out of.
                 let is_thread_local = self.tcx.get_attrs(def_id)[..]
                     .iter()
-                    .any(|attr| attr.check_name("thread_local"));
+                    .any(|attr| attr.check_name(sym::thread_local));
 
                 let cat = if is_thread_local {
                     let re = self.temporary_scope(hir_id.local_id);
diff --git a/src/librustc/middle/recursion_limit.rs b/src/librustc/middle/recursion_limit.rs
index ea077220e0b..5f355d17072 100644
--- a/src/librustc/middle/recursion_limit.rs
+++ b/src/librustc/middle/recursion_limit.rs
@@ -7,15 +7,16 @@
 
 use crate::session::Session;
 use syntax::ast;
+use syntax::symbol::{Symbol, sym};
 
 use rustc_data_structures::sync::Once;
 
 pub fn update_limits(sess: &Session, krate: &ast::Crate) {
-    update_limit(krate, &sess.recursion_limit, "recursion_limit", 64);
-    update_limit(krate, &sess.type_length_limit, "type_length_limit", 1048576);
+    update_limit(krate, &sess.recursion_limit, sym::recursion_limit, 64);
+    update_limit(krate, &sess.type_length_limit, sym::type_length_limit, 1048576);
 }
 
-fn update_limit(krate: &ast::Crate, limit: &Once<usize>, name: &str, default: usize) {
+fn update_limit(krate: &ast::Crate, limit: &Once<usize>, name: Symbol, default: usize) {
     for attr in &krate.attrs {
         if !attr.check_name(name) {
             continue;
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index d835d872d76..2402d0eefde 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -23,7 +23,7 @@ use std::mem::replace;
 use syntax::ast;
 use syntax::attr;
 use syntax::ptr::P;
-use syntax::symbol::keywords;
+use syntax::symbol::{keywords, sym};
 use syntax_pos::Span;
 
 use crate::hir::intravisit::{self, NestedVisitorMap, Visitor};
@@ -1285,7 +1285,7 @@ fn compute_object_lifetime_defaults(
                 let result = object_lifetime_defaults_for_item(tcx, generics);
 
                 // Debugging aid.
-                if attr::contains_name(&item.attrs, "rustc_object_lifetime_default") {
+                if attr::contains_name(&item.attrs, sym::rustc_object_lifetime_default) {
                     let object_lifetime_default_reprs: String = result
                         .iter()
                         .map(|set| match *set {
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index 5078bd7c594..c608c72430c 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -11,7 +11,7 @@ use crate::hir::intravisit::{self, Visitor, NestedVisitorMap};
 use crate::ty::query::Providers;
 use crate::middle::privacy::AccessLevels;
 use crate::session::{DiagnosticMessageId, Session};
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 use syntax_pos::{Span, MultiSpan};
 use syntax::ast::Attribute;
 use syntax::errors::Applicability;
@@ -669,7 +669,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
 
         match stability {
             Some(&Stability { level: attr::Unstable { reason, issue }, feature, .. }) => {
-                if span.allows_unstable(&feature.as_str()) {
+                if span.allows_unstable(feature) {
                     debug!("stability: skipping span={:?} since it is internal", span);
                     return EvalResult::Allow;
                 }
@@ -739,7 +739,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                 let error_id = (DiagnosticMessageId::StabilityId(issue), span_key, msg.clone());
                 let fresh = self.sess.one_time_diagnostics.borrow_mut().insert(error_id);
                 if fresh {
-                    emit_feature_err(&self.sess.parse_sess, &feature.as_str(), span,
+                    emit_feature_err(&self.sess.parse_sess, feature, span,
                                      GateIssue::Library(Some(issue)), &msg);
                 }
             }
@@ -802,13 +802,13 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
 
                 if adt_def.has_dtor(self.tcx) {
                     emit_feature_err(&self.tcx.sess.parse_sess,
-                                     "untagged_unions", item.span, GateIssue::Language,
+                                     sym::untagged_unions, item.span, GateIssue::Language,
                                      "unions with `Drop` implementations are unstable");
                 } else {
                     let param_env = self.tcx.param_env(def_id);
                     if !param_env.can_type_implement_copy(self.tcx, ty).is_ok() {
                         emit_feature_err(&self.tcx.sess.parse_sess,
-                                         "untagged_unions", item.span, GateIssue::Language,
+                                         sym::untagged_unions, item.span, GateIssue::Language,
                                          "unions with non-`Copy` fields are unstable");
                     }
                 }
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index 0e7b66b7444..2fff4c3f109 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -1052,7 +1052,7 @@ rustc_queries! {
     }
 
     Other {
-        query target_features_whitelist(_: CrateNum) -> Lrc<FxHashMap<String, Option<String>>> {
+        query target_features_whitelist(_: CrateNum) -> Lrc<FxHashMap<String, Option<Symbol>>> {
             eval_always
             desc { "looking up the whitelist of target features" }
         }
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index e8c7965ab4f..4d47491661e 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -29,6 +29,7 @@ use syntax::feature_gate::{self, AttributeType};
 use syntax::json::JsonEmitter;
 use syntax::source_map;
 use syntax::parse::{self, ParseSess};
+use syntax::symbol::Symbol;
 use syntax_pos::{MultiSpan, Span};
 use crate::util::profiling::SelfProfiler;
 
@@ -86,7 +87,7 @@ pub struct Session {
     /// in order to avoid redundantly verbose output (Issue #24690, #44953).
     pub one_time_diagnostics: Lock<FxHashSet<(DiagnosticMessageId, Option<Span>, String)>>,
     pub plugin_llvm_passes: OneThread<RefCell<Vec<String>>>,
-    pub plugin_attributes: Lock<Vec<(String, AttributeType)>>,
+    pub plugin_attributes: Lock<Vec<(Symbol, AttributeType)>>,
     pub crate_types: Once<Vec<config::CrateType>>,
     pub dependency_formats: Once<dependency_format::Dependencies>,
     /// The crate_disambiguator is constructed out of all the `-C metadata`
diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs
index 35d8e2beef5..afbce5a4f0a 100644
--- a/src/librustc/traits/coherence.rs
+++ b/src/librustc/traits/coherence.rs
@@ -4,17 +4,16 @@
 //! [trait-resolution]: https://rust-lang.github.io/rustc-guide/traits/resolution.html
 //! [trait-specialization]: https://rust-lang.github.io/rustc-guide/traits/specialization.html
 
-use crate::infer::CombinedSnapshot;
+use crate::infer::{CombinedSnapshot, InferOk};
 use crate::hir::def_id::{DefId, LOCAL_CRATE};
-use syntax_pos::DUMMY_SP;
 use crate::traits::{self, Normalized, SelectionContext, Obligation, ObligationCause};
 use crate::traits::IntercrateMode;
 use crate::traits::select::IntercrateAmbiguityCause;
 use crate::ty::{self, Ty, TyCtxt};
 use crate::ty::fold::TypeFoldable;
 use crate::ty::subst::Subst;
-
-use crate::infer::{InferOk};
+use syntax::symbol::sym;
+use syntax_pos::DUMMY_SP;
 
 /// Whether we do the orphan check relative to this crate or
 /// to some remote crate.
@@ -233,7 +232,7 @@ pub fn trait_ref_is_knowable<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
 pub fn trait_ref_is_local_or_fundamental<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
                                                          trait_ref: ty::TraitRef<'tcx>)
                                                          -> bool {
-    trait_ref.def_id.krate == LOCAL_CRATE || tcx.has_attr(trait_ref.def_id, "fundamental")
+    trait_ref.def_id.krate == LOCAL_CRATE || tcx.has_attr(trait_ref.def_id, sym::fundamental)
 }
 
 pub enum OrphanCheckErr<'tcx> {
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index d9ccbba69d5..df268839710 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -35,6 +35,7 @@ use crate::util::nodemap::{FxHashMap, FxHashSet};
 use errors::{Applicability, DiagnosticBuilder};
 use std::fmt;
 use syntax::ast;
+use syntax::symbol::sym;
 use syntax_pos::{DUMMY_SP, Span, ExpnInfo, ExpnFormat};
 
 impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
@@ -329,7 +330,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             return None
         };
 
-        if tcx.has_attr(impl_def_id, "rustc_on_unimplemented") {
+        if tcx.has_attr(impl_def_id, sym::rustc_on_unimplemented) {
             Some(impl_def_id)
         } else {
             None
diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs
index 2b286ee1b97..7ba7429f465 100644
--- a/src/librustc/traits/on_unimplemented.rs
+++ b/src/librustc/traits/on_unimplemented.rs
@@ -7,6 +7,7 @@ use crate::util::nodemap::FxHashMap;
 
 use syntax::ast::{MetaItem, NestedMetaItem};
 use syntax::attr;
+use syntax::symbol::sym;
 use syntax_pos::Span;
 use syntax_pos::symbol::LocalInternedString;
 
@@ -84,25 +85,25 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective {
         let mut note = None;
         let mut subcommands = vec![];
         for item in item_iter {
-            if item.check_name("message") && message.is_none() {
+            if item.check_name(sym::message) && message.is_none() {
                 if let Some(message_) = item.value_str() {
                     message = Some(OnUnimplementedFormatString::try_parse(
                         tcx, trait_def_id, message_.as_str(), span)?);
                     continue;
                 }
-            } else if item.check_name("label") && label.is_none() {
+            } else if item.check_name(sym::label) && label.is_none() {
                 if let Some(label_) = item.value_str() {
                     label = Some(OnUnimplementedFormatString::try_parse(
                         tcx, trait_def_id, label_.as_str(), span)?);
                     continue;
                 }
-            } else if item.check_name("note") && note.is_none() {
+            } else if item.check_name(sym::note) && note.is_none() {
                 if let Some(note_) = item.value_str() {
                     note = Some(OnUnimplementedFormatString::try_parse(
                         tcx, trait_def_id, note_.as_str(), span)?);
                     continue;
                 }
-            } else if item.check_name("on") && is_root &&
+            } else if item.check_name(sym::on) && is_root &&
                 message.is_none() && label.is_none() && note.is_none()
             {
                 if let Some(items) = item.meta_item_list() {
@@ -139,7 +140,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective {
     {
         let attrs = tcx.get_attrs(impl_def_id);
 
-        let attr = if let Some(item) = attr::find_by_name(&attrs, "rustc_on_unimplemented") {
+        let attr = if let Some(item) = attr::find_by_name(&attrs, sym::rustc_on_unimplemented) {
             item
         } else {
             return Ok(None);
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 15524ca6e93..c9fee02f66b 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -74,7 +74,7 @@ use syntax::ast;
 use syntax::attr;
 use syntax::source_map::MultiSpan;
 use syntax::feature_gate;
-use syntax::symbol::{Symbol, keywords, InternedString};
+use syntax::symbol::{Symbol, keywords, InternedString, sym};
 use syntax_pos::Span;
 
 use crate::hir;
@@ -1213,7 +1213,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             }
             span_bug!(attr.span, "no arguments to `rustc_layout_scalar_valid_range` attribute");
         };
-        (get("rustc_layout_scalar_valid_range_start"), get("rustc_layout_scalar_valid_range_end"))
+        (get(sym::rustc_layout_scalar_valid_range_start),
+         get(sym::rustc_layout_scalar_valid_range_end))
     }
 
     pub fn lift<T: ?Sized + Lift<'tcx>>(self, value: &T) -> Option<T::Lifted> {
@@ -3102,10 +3103,10 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
     };
     providers.is_panic_runtime = |tcx, cnum| {
         assert_eq!(cnum, LOCAL_CRATE);
-        attr::contains_name(tcx.hir().krate_attrs(), "panic_runtime")
+        attr::contains_name(tcx.hir().krate_attrs(), sym::panic_runtime)
     };
     providers.is_compiler_builtins = |tcx, cnum| {
         assert_eq!(cnum, LOCAL_CRATE);
-        attr::contains_name(tcx.hir().krate_attrs(), "compiler_builtins")
+        attr::contains_name(tcx.hir().krate_attrs(), sym::compiler_builtins)
     };
 }
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 7b749957c3f..2f71861d4dc 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -47,7 +47,7 @@ use std::ops::Range;
 use syntax::ast::{self, Name, Ident, NodeId};
 use syntax::attr;
 use syntax::ext::hygiene::Mark;
-use syntax::symbol::{keywords, Symbol, LocalInternedString, InternedString};
+use syntax::symbol::{keywords, sym, Symbol, LocalInternedString, InternedString};
 use syntax_pos::Span;
 
 use smallvec;
@@ -1875,11 +1875,11 @@ impl<'a, 'gcx, 'tcx> VariantDef {
         );
 
         let mut flags = VariantFlags::NO_VARIANT_FLAGS;
-        if adt_kind == AdtKind::Struct && tcx.has_attr(parent_did, "non_exhaustive") {
+        if adt_kind == AdtKind::Struct && tcx.has_attr(parent_did, sym::non_exhaustive) {
             debug!("found non-exhaustive field list for {:?}", parent_did);
             flags = flags | VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE;
         } else if let Some(variant_did) = variant_did {
-            if tcx.has_attr(variant_did, "non_exhaustive") {
+            if tcx.has_attr(variant_did, sym::non_exhaustive) {
                 debug!("found non-exhaustive field list for {:?}", variant_did);
                 flags = flags | VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE;
             }
@@ -2156,7 +2156,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
         debug!("AdtDef::new({:?}, {:?}, {:?}, {:?})", did, kind, variants, repr);
         let mut flags = AdtFlags::NO_ADT_FLAGS;
 
-        if kind == AdtKind::Enum && tcx.has_attr(did, "non_exhaustive") {
+        if kind == AdtKind::Enum && tcx.has_attr(did, sym::non_exhaustive) {
             debug!("found non-exhaustive variant list for {:?}", did);
             flags = flags | AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE;
         }
@@ -2172,7 +2172,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
         }
 
         let attrs = tcx.get_attrs(did);
-        if attr::contains_name(&attrs, "fundamental") {
+        if attr::contains_name(&attrs, sym::fundamental) {
             flags |= AdtFlags::IS_FUNDAMENTAL;
         }
         if Some(did) == tcx.lang_items().phantom_data() {
@@ -3030,7 +3030,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     }
 
     /// Determines whether an item is annotated with an attribute.
-    pub fn has_attr(self, did: DefId, attr: &str) -> bool {
+    pub fn has_attr(self, did: DefId, attr: Symbol) -> bool {
         attr::contains_name(&self.get_attrs(did), attr)
     }
 
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index 4c8ed71a57c..926c0f8b949 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -22,6 +22,7 @@ use rustc_macros::HashStable;
 use std::{cmp, fmt};
 use syntax::ast;
 use syntax::attr::{self, SignedInt, UnsignedInt};
+use syntax::symbol::sym;
 use syntax_pos::{Span, DUMMY_SP};
 
 #[derive(Copy, Clone, Debug)]
@@ -447,7 +448,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         // Such access can be in plain sight (e.g., dereferencing
         // `*foo.0` of `Foo<'a>(&'a u32)`) or indirectly hidden
         // (e.g., calling `foo.0.clone()` of `Foo<T:Clone>`).
-        if self.has_attr(dtor, "unsafe_destructor_blind_to_params") {
+        if self.has_attr(dtor, sym::unsafe_destructor_blind_to_params) {
             debug!("destructor_constraint({:?}) - blind", def.did);
             return vec![];
         }
diff --git a/src/librustc_allocator/expand.rs b/src/librustc_allocator/expand.rs
index 758a0d63886..0200e6c53b6 100644
--- a/src/librustc_allocator/expand.rs
+++ b/src/librustc_allocator/expand.rs
@@ -19,7 +19,7 @@ use syntax::{
     mut_visit::{self, MutVisitor},
     parse::ParseSess,
     ptr::P,
-    symbol::Symbol
+    symbol::{Symbol, sym}
 };
 use syntax_pos::Span;
 
@@ -58,7 +58,7 @@ impl MutVisitor for ExpandAllocatorDirectives<'_> {
     fn flat_map_item(&mut self, item: P<Item>) -> SmallVec<[P<Item>; 1]> {
         debug!("in submodule {}", self.in_submod);
 
-        let name = if attr::contains_name(&item.attrs, "global_allocator") {
+        let name = if attr::contains_name(&item.attrs, sym::global_allocator) {
             "global_allocator"
         } else {
             return mut_visit::noop_flat_map_item(item, self);
diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs
index b15a64c966b..f26684d9ef0 100644
--- a/src/librustc_codegen_llvm/attributes.rs
+++ b/src/librustc_codegen_llvm/attributes.rs
@@ -321,12 +321,12 @@ pub fn provide(providers: &mut Providers<'_>) {
             // rustdoc needs to be able to document functions that use all the features, so
             // whitelist them all
             Lrc::new(llvm_util::all_known_features()
-                .map(|(a, b)| (a.to_string(), b.map(|s| s.to_string())))
+                .map(|(a, b)| (a.to_string(), b))
                 .collect())
         } else {
             Lrc::new(llvm_util::target_feature_whitelist(tcx.sess)
                 .iter()
-                .map(|&(a, b)| (a.to_string(), b.map(|s| s.to_string())))
+                .map(|&(a, b)| (a.to_string(), b))
                 .collect())
         }
     };
diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs
index 8c83e9ef538..5f47108309f 100644
--- a/src/librustc_codegen_llvm/consts.rs
+++ b/src/librustc_codegen_llvm/consts.rs
@@ -14,6 +14,7 @@ use rustc::mir::interpret::{ConstValue, Allocation, read_target_uint,
 use rustc::hir::Node;
 use syntax_pos::Span;
 use rustc_target::abi::HasDataLayout;
+use syntax::symbol::sym;
 use syntax_pos::symbol::LocalInternedString;
 use rustc::ty::{self, Ty};
 use rustc_codegen_ssa::traits::*;
@@ -248,7 +249,7 @@ impl CodegenCx<'ll, 'tcx> {
             debug!("get_static: sym={} attrs={:?}", sym, attrs);
 
             for attr in attrs {
-                if attr.check_name("thread_local") {
+                if attr.check_name(sym::thread_local) {
                     llvm::set_thread_local_mode(g, self.tls_model);
                 }
             }
diff --git a/src/librustc_codegen_llvm/debuginfo/gdb.rs b/src/librustc_codegen_llvm/debuginfo/gdb.rs
index 91496ffbe55..04c9e93c7a5 100644
--- a/src/librustc_codegen_llvm/debuginfo/gdb.rs
+++ b/src/librustc_codegen_llvm/debuginfo/gdb.rs
@@ -9,6 +9,7 @@ use rustc::session::config::DebugInfo;
 use rustc_codegen_ssa::traits::*;
 
 use syntax::attr;
+use syntax::symbol::sym;
 
 
 /// Inserts a side-effect free instruction sequence that makes sure that the
@@ -66,8 +67,7 @@ pub fn get_or_insert_gdb_debug_scripts_section_global(cx: &CodegenCx<'ll, '_>)
 
 pub fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool {
     let omit_gdb_pretty_printer_section =
-        attr::contains_name(&cx.tcx.hir().krate_attrs(),
-                            "omit_gdb_pretty_printer_section");
+        attr::contains_name(&cx.tcx.hir().krate_attrs(), sym::omit_gdb_pretty_printer_section);
 
     !omit_gdb_pretty_printer_section &&
     cx.sess().opts.debuginfo != DebugInfo::None &&
diff --git a/src/librustc_codegen_llvm/llvm_util.rs b/src/librustc_codegen_llvm/llvm_util.rs
index f1b8d532eeb..274c8965962 100644
--- a/src/librustc_codegen_llvm/llvm_util.rs
+++ b/src/librustc_codegen_llvm/llvm_util.rs
@@ -7,6 +7,7 @@ use rustc_target::spec::MergeFunctions;
 use libc::c_int;
 use std::ffi::CString;
 use syntax::feature_gate::UnstableFeatures;
+use syntax::symbol::sym;
 
 use std::str;
 use std::slice;
@@ -93,106 +94,106 @@ unsafe fn configure_llvm(sess: &Session) {
 // to LLVM or the feature detection code will walk past the end of the feature
 // array, leading to crashes.
 
-const ARM_WHITELIST: &[(&str, Option<&str>)] = &[
-    ("aclass", Some("arm_target_feature")),
-    ("mclass", Some("arm_target_feature")),
-    ("rclass", Some("arm_target_feature")),
-    ("dsp", Some("arm_target_feature")),
-    ("neon", Some("arm_target_feature")),
-    ("v5te", Some("arm_target_feature")),
-    ("v6", Some("arm_target_feature")),
-    ("v6k", Some("arm_target_feature")),
-    ("v6t2", Some("arm_target_feature")),
-    ("v7", Some("arm_target_feature")),
-    ("v8", Some("arm_target_feature")),
-    ("vfp2", Some("arm_target_feature")),
-    ("vfp3", Some("arm_target_feature")),
-    ("vfp4", Some("arm_target_feature")),
+const ARM_WHITELIST: &[(&str, Option<Symbol>)] = &[
+    ("aclass", Some(sym::arm_target_feature)),
+    ("mclass", Some(sym::arm_target_feature)),
+    ("rclass", Some(sym::arm_target_feature)),
+    ("dsp", Some(sym::arm_target_feature)),
+    ("neon", Some(sym::arm_target_feature)),
+    ("v5te", Some(sym::arm_target_feature)),
+    ("v6", Some(sym::arm_target_feature)),
+    ("v6k", Some(sym::arm_target_feature)),
+    ("v6t2", Some(sym::arm_target_feature)),
+    ("v7", Some(sym::arm_target_feature)),
+    ("v8", Some(sym::arm_target_feature)),
+    ("vfp2", Some(sym::arm_target_feature)),
+    ("vfp3", Some(sym::arm_target_feature)),
+    ("vfp4", Some(sym::arm_target_feature)),
 ];
 
-const AARCH64_WHITELIST: &[(&str, Option<&str>)] = &[
-    ("fp", Some("aarch64_target_feature")),
-    ("neon", Some("aarch64_target_feature")),
-    ("sve", Some("aarch64_target_feature")),
-    ("crc", Some("aarch64_target_feature")),
-    ("crypto", Some("aarch64_target_feature")),
-    ("ras", Some("aarch64_target_feature")),
-    ("lse", Some("aarch64_target_feature")),
-    ("rdm", Some("aarch64_target_feature")),
-    ("fp16", Some("aarch64_target_feature")),
-    ("rcpc", Some("aarch64_target_feature")),
-    ("dotprod", Some("aarch64_target_feature")),
-    ("v8.1a", Some("aarch64_target_feature")),
-    ("v8.2a", Some("aarch64_target_feature")),
-    ("v8.3a", Some("aarch64_target_feature")),
+const AARCH64_WHITELIST: &[(&str, Option<Symbol>)] = &[
+    ("fp", Some(sym::aarch64_target_feature)),
+    ("neon", Some(sym::aarch64_target_feature)),
+    ("sve", Some(sym::aarch64_target_feature)),
+    ("crc", Some(sym::aarch64_target_feature)),
+    ("crypto", Some(sym::aarch64_target_feature)),
+    ("ras", Some(sym::aarch64_target_feature)),
+    ("lse", Some(sym::aarch64_target_feature)),
+    ("rdm", Some(sym::aarch64_target_feature)),
+    ("fp16", Some(sym::aarch64_target_feature)),
+    ("rcpc", Some(sym::aarch64_target_feature)),
+    ("dotprod", Some(sym::aarch64_target_feature)),
+    ("v8.1a", Some(sym::aarch64_target_feature)),
+    ("v8.2a", Some(sym::aarch64_target_feature)),
+    ("v8.3a", Some(sym::aarch64_target_feature)),
 ];
 
-const X86_WHITELIST: &[(&str, Option<&str>)] = &[
-    ("adx", Some("adx_target_feature")),
+const X86_WHITELIST: &[(&str, Option<Symbol>)] = &[
+    ("adx", Some(sym::adx_target_feature)),
     ("aes", None),
     ("avx", None),
     ("avx2", None),
-    ("avx512bw", Some("avx512_target_feature")),
-    ("avx512cd", Some("avx512_target_feature")),
-    ("avx512dq", Some("avx512_target_feature")),
-    ("avx512er", Some("avx512_target_feature")),
-    ("avx512f", Some("avx512_target_feature")),
-    ("avx512ifma", Some("avx512_target_feature")),
-    ("avx512pf", Some("avx512_target_feature")),
-    ("avx512vbmi", Some("avx512_target_feature")),
-    ("avx512vl", Some("avx512_target_feature")),
-    ("avx512vpopcntdq", Some("avx512_target_feature")),
+    ("avx512bw", Some(sym::avx512_target_feature)),
+    ("avx512cd", Some(sym::avx512_target_feature)),
+    ("avx512dq", Some(sym::avx512_target_feature)),
+    ("avx512er", Some(sym::avx512_target_feature)),
+    ("avx512f", Some(sym::avx512_target_feature)),
+    ("avx512ifma", Some(sym::avx512_target_feature)),
+    ("avx512pf", Some(sym::avx512_target_feature)),
+    ("avx512vbmi", Some(sym::avx512_target_feature)),
+    ("avx512vl", Some(sym::avx512_target_feature)),
+    ("avx512vpopcntdq", Some(sym::avx512_target_feature)),
     ("bmi1", None),
     ("bmi2", None),
-    ("cmpxchg16b", Some("cmpxchg16b_target_feature")),
-    ("f16c", Some("f16c_target_feature")),
+    ("cmpxchg16b", Some(sym::cmpxchg16b_target_feature)),
+    ("f16c", Some(sym::f16c_target_feature)),
     ("fma", None),
     ("fxsr", None),
     ("lzcnt", None),
-    ("mmx", Some("mmx_target_feature")),
-    ("movbe", Some("movbe_target_feature")),
+    ("mmx", Some(sym::mmx_target_feature)),
+    ("movbe", Some(sym::movbe_target_feature)),
     ("pclmulqdq", None),
     ("popcnt", None),
     ("rdrand", None),
     ("rdseed", None),
-    ("rtm", Some("rtm_target_feature")),
+    ("rtm", Some(sym::rtm_target_feature)),
     ("sha", None),
     ("sse", None),
     ("sse2", None),
     ("sse3", None),
     ("sse4.1", None),
     ("sse4.2", None),
-    ("sse4a", Some("sse4a_target_feature")),
+    ("sse4a", Some(sym::sse4a_target_feature)),
     ("ssse3", None),
-    ("tbm", Some("tbm_target_feature")),
+    ("tbm", Some(sym::tbm_target_feature)),
     ("xsave", None),
     ("xsavec", None),
     ("xsaveopt", None),
     ("xsaves", None),
 ];
 
-const HEXAGON_WHITELIST: &[(&str, Option<&str>)] = &[
-    ("hvx", Some("hexagon_target_feature")),
-    ("hvx-double", Some("hexagon_target_feature")),
+const HEXAGON_WHITELIST: &[(&str, Option<Symbol>)] = &[
+    ("hvx", Some(sym::hexagon_target_feature)),
+    ("hvx-double", Some(sym::hexagon_target_feature)),
 ];
 
-const POWERPC_WHITELIST: &[(&str, Option<&str>)] = &[
-    ("altivec", Some("powerpc_target_feature")),
-    ("power8-altivec", Some("powerpc_target_feature")),
-    ("power9-altivec", Some("powerpc_target_feature")),
-    ("power8-vector", Some("powerpc_target_feature")),
-    ("power9-vector", Some("powerpc_target_feature")),
-    ("vsx", Some("powerpc_target_feature")),
+const POWERPC_WHITELIST: &[(&str, Option<Symbol>)] = &[
+    ("altivec", Some(sym::powerpc_target_feature)),
+    ("power8-altivec", Some(sym::powerpc_target_feature)),
+    ("power9-altivec", Some(sym::powerpc_target_feature)),
+    ("power8-vector", Some(sym::powerpc_target_feature)),
+    ("power9-vector", Some(sym::powerpc_target_feature)),
+    ("vsx", Some(sym::powerpc_target_feature)),
 ];
 
-const MIPS_WHITELIST: &[(&str, Option<&str>)] = &[
-    ("fp64", Some("mips_target_feature")),
-    ("msa", Some("mips_target_feature")),
+const MIPS_WHITELIST: &[(&str, Option<Symbol>)] = &[
+    ("fp64", Some(sym::mips_target_feature)),
+    ("msa", Some(sym::mips_target_feature)),
 ];
 
-const WASM_WHITELIST: &[(&str, Option<&str>)] = &[
-    ("simd128", Some("wasm_target_feature")),
-    ("atomics", Some("wasm_target_feature")),
+const WASM_WHITELIST: &[(&str, Option<Symbol>)] = &[
+    ("simd128", Some(sym::wasm_target_feature)),
+    ("atomics", Some(sym::wasm_target_feature)),
 ];
 
 /// When rustdoc is running, provide a list of all known features so that all their respective
@@ -200,7 +201,7 @@ const WASM_WHITELIST: &[(&str, Option<&str>)] = &[
 ///
 /// IMPORTANT: If you're adding another whitelist to the above lists, make sure to add it to this
 /// iterator!
-pub fn all_known_features() -> impl Iterator<Item=(&'static str, Option<&'static str>)> {
+pub fn all_known_features() -> impl Iterator<Item=(&'static str, Option<Symbol>)> {
     ARM_WHITELIST.iter().cloned()
         .chain(AARCH64_WHITELIST.iter().cloned())
         .chain(X86_WHITELIST.iter().cloned())
@@ -247,7 +248,7 @@ pub fn target_features(sess: &Session) -> Vec<Symbol> {
 }
 
 pub fn target_feature_whitelist(sess: &Session)
-    -> &'static [(&'static str, Option<&'static str>)]
+    -> &'static [(&'static str, Option<Symbol>)]
 {
     match &*sess.target.target.arch {
         "arm" => ARM_WHITELIST,
diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs
index 576bcc8f38e..204ca59efc8 100644
--- a/src/librustc_codegen_ssa/back/write.rs
+++ b/src/librustc_codegen_ssa/back/write.rs
@@ -28,7 +28,7 @@ use rustc_target::spec::MergeFunctions;
 use syntax::attr;
 use syntax::ext::hygiene::Mark;
 use syntax_pos::MultiSpan;
-use syntax_pos::symbol::Symbol;
+use syntax_pos::symbol::{Symbol, sym};
 use jobserver::{Client, Acquired};
 
 use std::any::Any;
@@ -382,9 +382,9 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
     let sess = tcx.sess;
     let crate_name = tcx.crate_name(LOCAL_CRATE);
     let crate_hash = tcx.crate_hash(LOCAL_CRATE);
-    let no_builtins = attr::contains_name(&tcx.hir().krate().attrs, "no_builtins");
+    let no_builtins = attr::contains_name(&tcx.hir().krate().attrs, sym::no_builtins);
     let subsystem = attr::first_attr_value_str_by_name(&tcx.hir().krate().attrs,
-                                                       "windows_subsystem");
+                                                       sym::windows_subsystem);
     let windows_subsystem = subsystem.map(|subsystem| {
         if subsystem != "windows" && subsystem != "console" {
             tcx.sess.fatal(&format!("invalid windows subsystem `{}`, only \
diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs
index 8d3e64c1aa6..586db5cfabe 100644
--- a/src/librustc_codegen_ssa/mir/rvalue.rs
+++ b/src/librustc_codegen_ssa/mir/rvalue.rs
@@ -5,6 +5,7 @@ use rustc::mir;
 use rustc::middle::lang_items::ExchangeMallocFnLangItem;
 use rustc_apfloat::{ieee, Float, Status, Round};
 use std::{u128, i128};
+use syntax::symbol::sym;
 
 use crate::base;
 use crate::MemFlags;
@@ -181,9 +182,8 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     mir::CastKind::Pointer(PointerCast::ReifyFnPointer) => {
                         match operand.layout.ty.sty {
                             ty::FnDef(def_id, substs) => {
-                                if bx.cx().tcx().has_attr(def_id, "rustc_args_required_const") {
-                                    bug!("reifying a fn ptr that requires \
-                                          const arguments");
+                                if bx.cx().tcx().has_attr(def_id, sym::rustc_args_required_const) {
+                                    bug!("reifying a fn ptr that requires const arguments");
                                 }
                                 OperandValue::Immediate(
                                     callee::resolve_and_get_fn(bx.cx(), def_id, substs))
diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs
index 437515f1e9a..b4ba90c61f6 100644
--- a/src/librustc_codegen_utils/lib.rs
+++ b/src/librustc_codegen_utils/lib.rs
@@ -23,6 +23,7 @@ extern crate rustc;
 
 use rustc::ty::TyCtxt;
 use rustc::hir::def_id::LOCAL_CRATE;
+use syntax::symbol::sym;
 
 pub mod link;
 pub mod codegen_backend;
@@ -35,7 +36,7 @@ pub mod symbol_names_test;
 /// reporting an error.
 pub fn check_for_rustc_errors_attr(tcx: TyCtxt<'_, '_, '_>) {
     if let Some((def_id, _)) = tcx.entry_fn(LOCAL_CRATE) {
-        if tcx.has_attr(def_id, "rustc_error") {
+        if tcx.has_attr(def_id, sym::rustc_error) {
             tcx.sess.span_fatal(tcx.def_span(def_id), "compilation successful");
         }
     }
diff --git a/src/librustc_codegen_utils/link.rs b/src/librustc_codegen_utils/link.rs
index f3a1b219f8a..30f37fefa7c 100644
--- a/src/librustc_codegen_utils/link.rs
+++ b/src/librustc_codegen_utils/link.rs
@@ -2,6 +2,7 @@ use rustc::session::config::{self, OutputFilenames, Input, OutputType};
 use rustc::session::Session;
 use std::path::{Path, PathBuf};
 use syntax::{ast, attr};
+use syntax::symbol::sym;
 use syntax_pos::Span;
 
 pub fn out_filename(sess: &Session,
@@ -49,7 +50,7 @@ pub fn find_crate_name(sess: Option<&Session>,
     // as used. After doing this, however, we still prioritize a crate name from
     // the command line over one found in the #[crate_name] attribute. If we
     // find both we ensure that they're the same later on as well.
-    let attr_crate_name = attr::find_by_name(attrs, "crate_name")
+    let attr_crate_name = attr::find_by_name(attrs, sym::crate_name)
         .and_then(|at| at.value_str().map(|s| (at, s)));
 
     if let Some(sess) = sess {
diff --git a/src/librustc_codegen_utils/symbol_names_test.rs b/src/librustc_codegen_utils/symbol_names_test.rs
index 6a2b6f1321b..27ae0b97e59 100644
--- a/src/librustc_codegen_utils/symbol_names_test.rs
+++ b/src/librustc_codegen_utils/symbol_names_test.rs
@@ -6,11 +6,11 @@
 
 use rustc::hir;
 use rustc::ty::TyCtxt;
-
 use rustc_mir::monomorphize::Instance;
+use syntax::symbol::{Symbol, sym};
 
-const SYMBOL_NAME: &'static str = "rustc_symbol_name";
-const DEF_PATH: &'static str = "rustc_def_path";
+const SYMBOL_NAME: Symbol = sym::rustc_symbol_name;
+const DEF_PATH: Symbol = sym::rustc_def_path;
 
 pub fn report_symbol_names<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     // if the `rustc_attrs` feature is not enabled, then the
diff --git a/src/librustc_incremental/assert_module_sources.rs b/src/librustc_incremental/assert_module_sources.rs
index 2c83501c86f..04dad9c5355 100644
--- a/src/librustc_incremental/assert_module_sources.rs
+++ b/src/librustc_incremental/assert_module_sources.rs
@@ -27,12 +27,13 @@ use rustc::mir::mono::CodegenUnitNameBuilder;
 use rustc::ty::TyCtxt;
 use std::collections::BTreeSet;
 use syntax::ast;
+use syntax::symbol::{Symbol, sym};
 use rustc::ich::{ATTR_PARTITION_REUSED, ATTR_PARTITION_CODEGENED,
                  ATTR_EXPECTED_CGU_REUSE};
 
-const MODULE: &str = "module";
-const CFG: &str = "cfg";
-const KIND: &str = "kind";
+const MODULE: Symbol = sym::module;
+const CFG: Symbol = sym::cfg;
+const KIND: Symbol = sym::kind;
 
 pub fn assert_module_sources<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     tcx.dep_graph.with_ignore(|| {
@@ -146,7 +147,7 @@ impl<'a, 'tcx> AssertModuleSource<'a, 'tcx> {
                                                         comp_kind);
     }
 
-    fn field(&self, attr: &ast::Attribute, name: &str) -> ast::Name {
+    fn field(&self, attr: &ast::Attribute, name: Symbol) -> ast::Name {
         for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
             if item.check_name(name) {
                 if let Some(value) = item.value_str() {
diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs
index 6f5b411946c..f404a4f82e6 100644
--- a/src/librustc_incremental/persist/dirty_clean.rs
+++ b/src/librustc_incremental/persist/dirty_clean.rs
@@ -23,14 +23,15 @@ use rustc::hir::def_id::DefId;
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
 use rustc::hir::intravisit;
 use rustc::ich::{ATTR_DIRTY, ATTR_CLEAN};
-use syntax::ast::{self, Attribute, NestedMetaItem};
+use rustc::ty::TyCtxt;
 use rustc_data_structures::fx::FxHashSet;
+use syntax::ast::{self, Attribute, NestedMetaItem};
+use syntax::symbol::{Symbol, sym};
 use syntax_pos::Span;
-use rustc::ty::TyCtxt;
 
-const EXCEPT: &str = "except";
-const LABEL: &str = "label";
-const CFG: &str = "cfg";
+const EXCEPT: Symbol = sym::except;
+const LABEL: Symbol = sym::label;
+const CFG: Symbol = sym::cfg;
 
 // Base and Extra labels to build up the labels
 
@@ -591,7 +592,7 @@ fn expect_associated_value(tcx: TyCtxt<'_, '_, '_>, item: &NestedMetaItem) -> as
 // nodes.
 pub struct FindAllAttrs<'a, 'tcx:'a> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    attr_names: Vec<&'static str>,
+    attr_names: Vec<Symbol>,
     found_attrs: Vec<&'tcx Attribute>,
 }
 
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index 54b3e734205..c5ac8860ccd 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -230,7 +230,7 @@ impl BoxedResolver {
 
 pub struct PluginInfo {
     syntax_exts: Vec<NamedSyntaxExtension>,
-    attributes: Vec<(String, AttributeType)>,
+    attributes: Vec<(Symbol, AttributeType)>,
 }
 
 pub fn register_plugins<'a>(
diff --git a/src/librustc_interface/proc_macro_decls.rs b/src/librustc_interface/proc_macro_decls.rs
index 8ed03efd1a7..e9f2f0410d4 100644
--- a/src/librustc_interface/proc_macro_decls.rs
+++ b/src/librustc_interface/proc_macro_decls.rs
@@ -4,6 +4,7 @@ use rustc::hir;
 use rustc::ty::TyCtxt;
 use rustc::ty::query::Providers;
 use syntax::attr;
+use syntax::symbol::sym;
 
 pub fn find<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) -> Option<DefId> {
     tcx.proc_macro_decls_static(LOCAL_CRATE)
@@ -27,7 +28,7 @@ struct Finder {
 
 impl<'v> ItemLikeVisitor<'v> for Finder {
     fn visit_item(&mut self, item: &hir::Item) {
-        if attr::contains_name(&item.attrs, "rustc_proc_macro_decls") {
+        if attr::contains_name(&item.attrs, sym::rustc_proc_macro_decls) {
             self.decls = Some(item.hir_id);
         }
     }
diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs
index 17523aedffb..2b1a993d1cc 100644
--- a/src/librustc_interface/util.rs
+++ b/src/librustc_interface/util.rs
@@ -35,7 +35,7 @@ use syntax::mut_visit::{*, MutVisitor, visit_clobber};
 use syntax::ast::BlockCheckMode;
 use syntax::util::lev_distance::find_best_match_for_name;
 use syntax::source_map::{FileLoader, RealFileLoader, SourceMap};
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 use syntax::{self, ast, attr};
 #[cfg(not(parallel_compiler))]
 use std::{thread, panic};
@@ -495,7 +495,7 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<c
     let attr_types: Vec<config::CrateType> = attrs
         .iter()
         .filter_map(|a| {
-            if a.check_name("crate_type") {
+            if a.check_name(sym::crate_type) {
                 match a.value_str() {
                     Some(ref n) if *n == "rlib" => Some(config::CrateType::Rlib),
                     Some(ref n) if *n == "dylib" => Some(config::CrateType::Dylib),
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index f7a89271ec5..af4f1b88b0f 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -42,7 +42,7 @@ use syntax::edition::Edition;
 use syntax::feature_gate::{AttributeGate, AttributeTemplate, AttributeType};
 use syntax::feature_gate::{Stability, deprecated_attributes};
 use syntax_pos::{BytePos, Span, SyntaxContext};
-use syntax::symbol::{Symbol, keywords};
+use syntax::symbol::{Symbol, keywords, sym};
 use syntax::errors::{Applicability, DiagnosticBuilder};
 use syntax::print::pprust::expr_to_string;
 use syntax::visit::FnKind;
@@ -207,7 +207,7 @@ impl UnsafeCode {
 
 impl EarlyLintPass for UnsafeCode {
     fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) {
-        if attr.check_name("allow_internal_unsafe") {
+        if attr.check_name(sym::allow_internal_unsafe) {
             self.report_unsafe(cx, attr.span, "`allow_internal_unsafe` allows defining \
                                                macros using unsafe without triggering \
                                                the `unsafe_code` lint at their call site");
@@ -285,7 +285,7 @@ pub struct MissingDoc {
 impl_lint_pass!(MissingDoc => [MISSING_DOCS]);
 
 fn has_doc(attr: &ast::Attribute) -> bool {
-    if !attr.check_name("doc") {
+    if !attr.check_name(sym::doc) {
         return false;
     }
 
@@ -295,7 +295,7 @@ fn has_doc(attr: &ast::Attribute) -> bool {
 
     if let Some(list) = attr.meta_item_list() {
         for meta in list {
-            if meta.check_name("include") || meta.check_name("hidden") {
+            if meta.check_name(sym::include) || meta.check_name(sym::hidden) {
                 return true;
             }
         }
@@ -355,10 +355,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc {
     fn enter_lint_attrs(&mut self, _: &LateContext<'_, '_>, attrs: &[ast::Attribute]) {
         let doc_hidden = self.doc_hidden() ||
                          attrs.iter().any(|attr| {
-            attr.check_name("doc") &&
+            attr.check_name(sym::doc) &&
             match attr.meta_item_list() {
                 None => false,
-                Some(l) => attr::list_contains_name(&l, "hidden"),
+                Some(l) => attr::list_contains_name(&l, sym::hidden),
             }
         });
         self.doc_hidden_stack.push(doc_hidden);
@@ -723,7 +723,7 @@ impl UnusedDocComment {
 
             let span = sugared_span.take().unwrap_or_else(|| attr.span);
 
-            if attr.check_name("doc") {
+            if attr.check_name(sym::doc) {
                 let mut err = cx.struct_span_lint(UNUSED_DOC_COMMENTS, span, "unused doc comment");
 
                 err.span_label(
@@ -829,7 +829,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems {
     fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
         match it.node {
             hir::ItemKind::Fn(.., ref generics, _) => {
-                if let Some(no_mangle_attr) = attr::find_by_name(&it.attrs, "no_mangle") {
+                if let Some(no_mangle_attr) = attr::find_by_name(&it.attrs, sym::no_mangle) {
                     for param in &generics.params {
                         match param.kind {
                             GenericParamKind::Lifetime { .. } => {}
@@ -856,7 +856,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems {
                 }
             }
             hir::ItemKind::Const(..) => {
-                if attr::contains_name(&it.attrs, "no_mangle") {
+                if attr::contains_name(&it.attrs, sym::no_mangle) {
                     // Const items do not refer to a particular location in memory, and therefore
                     // don't have anything to attach a symbol to
                     let msg = "const items should never be #[no_mangle]";
@@ -947,7 +947,7 @@ declare_lint_pass!(
 
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnstableFeatures {
     fn check_attribute(&mut self, ctx: &LateContext<'_, '_>, attr: &ast::Attribute) {
-        if attr.check_name("feature") {
+        if attr.check_name(sym::feature) {
             if let Some(items) = attr.meta_item_list() {
                 for item in items {
                     ctx.span_lint(UNSTABLE_FEATURES, item.span(), "unstable feature");
@@ -1382,7 +1382,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnameableTestItems {
             return;
         }
 
-        if let Some(attr) = attr::find_by_name(&it.attrs, "rustc_test_marker") {
+        if let Some(attr) = attr::find_by_name(&it.attrs, sym::rustc_test_marker) {
             cx.struct_span_lint(
                 UNNAMEABLE_TEST_ITEMS,
                 attr.span,
diff --git a/src/librustc_lint/nonstandard_style.rs b/src/librustc_lint/nonstandard_style.rs
index 7a003d14b2b..551eded9858 100644
--- a/src/librustc_lint/nonstandard_style.rs
+++ b/src/librustc_lint/nonstandard_style.rs
@@ -9,6 +9,7 @@ use lint::{EarlyLintPass, LintPass, LateLintPass};
 use syntax::ast;
 use syntax::attr;
 use syntax::errors::Applicability;
+use syntax::symbol::sym;
 use syntax_pos::{BytePos, symbol::Ident, Span};
 
 #[derive(PartialEq)]
@@ -253,7 +254,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase {
         let crate_ident = if let Some(name) = &cx.tcx.sess.opts.crate_name {
             Some(Ident::from_str(name))
         } else {
-            attr::find_by_name(&cx.tcx.hir().attrs_by_hir_id(hir::CRATE_HIR_ID), "crate_name")
+            attr::find_by_name(&cx.tcx.hir().attrs_by_hir_id(hir::CRATE_HIR_ID), sym::crate_name)
                 .and_then(|attr| attr.meta())
                 .and_then(|meta| {
                     meta.name_value_literal().and_then(|lit| {
@@ -315,7 +316,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase {
             }
             FnKind::ItemFn(ident, _, header, _, attrs) => {
                 // Skip foreign-ABI #[no_mangle] functions (Issue #31924)
-                if header.abi != Abi::Rust && attr::contains_name(attrs, "no_mangle") {
+                if header.abi != Abi::Rust && attr::contains_name(attrs, sym::no_mangle) {
                     return;
                 }
                 self.check_snake_case(cx, "function", ident);
@@ -390,7 +391,7 @@ impl NonUpperCaseGlobals {
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonUpperCaseGlobals {
     fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
         match it.node {
-            hir::ItemKind::Static(..) if !attr::contains_name(&it.attrs, "no_mangle") => {
+            hir::ItemKind::Static(..) if !attr::contains_name(&it.attrs, sym::no_mangle) => {
                 NonUpperCaseGlobals::check_upper_case(cx, "static variable", &it.ident);
             }
             hir::ItemKind::Const(..) => {
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index 92508ad51f1..93af7a1cd8f 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -12,7 +12,7 @@ use syntax::attr;
 use syntax::errors::Applicability;
 use syntax::feature_gate::{AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
 use syntax::print::pprust;
-use syntax::symbol::keywords;
+use syntax::symbol::{keywords, sym};
 use syntax::symbol::Symbol;
 use syntax::util::parser;
 use syntax_pos::Span;
@@ -170,7 +170,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
             descr_post_path: &str,
         ) -> bool {
             for attr in cx.tcx.get_attrs(def_id).iter() {
-                if attr.check_name("must_use") {
+                if attr.check_name(sym::must_use) {
                     let msg = format!("unused {}`{}`{} that must be used",
                         descr_pre_path, cx.tcx.def_path_str(def_id), descr_post_path);
                     let mut err = cx.struct_span_lint(UNUSED_MUST_USE, sp, &msg);
@@ -243,8 +243,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAttributes {
         }
 
         let plugin_attributes = cx.sess().plugin_attributes.borrow_mut();
-        for &(ref name, ty) in plugin_attributes.iter() {
-            if ty == AttributeType::Whitelisted && attr.check_name(&**name) {
+        for &(name, ty) in plugin_attributes.iter() {
+            if ty == AttributeType::Whitelisted && attr.check_name(name) {
                 debug!("{:?} (plugin attr) is whitelisted with ty {:?}", name, ty);
                 break;
             }
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index c47d7d85a37..20caad70f2b 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -27,7 +27,7 @@ use std::{cmp, fs};
 use syntax::ast;
 use syntax::attr;
 use syntax::ext::base::SyntaxExtension;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 use syntax::visit;
 use syntax::{span_err, span_fatal};
 use syntax_pos::{Span, DUMMY_SP};
@@ -704,7 +704,7 @@ impl<'a> CrateLoader<'a> {
         let desired_strategy = self.sess.panic_strategy();
         let mut runtime_found = false;
         let mut needs_panic_runtime = attr::contains_name(&krate.attrs,
-                                                          "needs_panic_runtime");
+                                                          sym::needs_panic_runtime);
 
         self.cstore.iter_crate_data(|cnum, data| {
             needs_panic_runtime = needs_panic_runtime ||
@@ -898,7 +898,7 @@ impl<'a> CrateLoader<'a> {
         // about through the `#![needs_allocator]` attribute and is typically
         // written down in liballoc.
         let mut needs_allocator = attr::contains_name(&krate.attrs,
-                                                      "needs_allocator");
+                                                      sym::needs_allocator);
         self.cstore.iter_crate_data(|_, data| {
             needs_allocator = needs_allocator || data.root.needs_allocator;
         });
@@ -964,7 +964,7 @@ impl<'a> CrateLoader<'a> {
         // allocator. At this point our allocator request is typically fulfilled
         // by the standard library, denoted by the `#![default_lib_allocator]`
         // attribute.
-        let mut has_default = attr::contains_name(&krate.attrs, "default_lib_allocator");
+        let mut has_default = attr::contains_name(&krate.attrs, sym::default_lib_allocator);
         self.cstore.iter_crate_data(|_, data| {
             if data.root.has_default_lib_allocator {
                 has_default = true;
@@ -987,7 +987,7 @@ impl<'a> CrateLoader<'a> {
 
             impl<'ast> visit::Visitor<'ast> for Finder {
                 fn visit_item(&mut self, i: &'ast ast::Item) {
-                    if attr::contains_name(&i.attrs, "global_allocator") {
+                    if attr::contains_name(&i.attrs, sym::global_allocator) {
                         self.0 = true;
                     }
                     visit::walk_item(self, i)
@@ -1065,7 +1065,7 @@ impl<'a> CrateLoader<'a> {
                     }
                     None => item.ident.name,
                 };
-                let dep_kind = if attr::contains_name(&item.attrs, "no_link") {
+                let dep_kind = if attr::contains_name(&item.attrs, sym::no_link) {
                     DepKind::UnexportedMacrosOnly
                 } else {
                     DepKind::Explicit
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 4b9db466da8..e950c2815e9 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -29,7 +29,7 @@ use rustc_serialize::{Decodable, Decoder, SpecializedDecoder, opaque};
 use syntax::attr;
 use syntax::ast::{self, Ident};
 use syntax::source_map;
-use syntax::symbol::InternedString;
+use syntax::symbol::{InternedString, sym};
 use syntax::ext::base::{MacroKind, SyntaxExtension};
 use syntax::ext::hygiene::Mark;
 use syntax_pos::{self, Span, BytePos, Pos, DUMMY_SP, NO_EXPANSION};
@@ -841,7 +841,7 @@ impl<'a, 'tcx> CrateMetadata {
                                 // for other constructors correct visibilities
                                 // were already encoded in metadata.
                                 let attrs = self.get_item_attrs(def_id.index, sess);
-                                if attr::contains_name(&attrs, "non_exhaustive") {
+                                if attr::contains_name(&attrs, sym::non_exhaustive) {
                                     let crate_def_id = self.local_def_id(CRATE_DEF_INDEX);
                                     vis = ty::Visibility::Restricted(crate_def_id);
                                 }
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index 0946dad5320..0ac03526832 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -33,7 +33,7 @@ use std::u32;
 use syntax::ast;
 use syntax::attr;
 use syntax::source_map::Spanned;
-use syntax::symbol::keywords;
+use syntax::symbol::{keywords, sym};
 use syntax_pos::{self, hygiene, FileName, SourceFile, Span};
 use log::{debug, trace};
 
@@ -469,7 +469,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
 
         let attrs = tcx.hir().krate_attrs();
         let is_proc_macro = tcx.sess.crate_types.borrow().contains(&CrateType::ProcMacro);
-        let has_default_lib_allocator = attr::contains_name(&attrs, "default_lib_allocator");
+        let has_default_lib_allocator = attr::contains_name(&attrs, sym::default_lib_allocator);
         let has_global_allocator = *tcx.sess.has_global_allocator.get();
         let has_panic_handler = *tcx.sess.has_panic_handler.try_get().unwrap_or(&false);
 
@@ -496,13 +496,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             } else {
                 None
             },
-            compiler_builtins: attr::contains_name(&attrs, "compiler_builtins"),
-            needs_allocator: attr::contains_name(&attrs, "needs_allocator"),
-            needs_panic_runtime: attr::contains_name(&attrs, "needs_panic_runtime"),
-            no_builtins: attr::contains_name(&attrs, "no_builtins"),
-            panic_runtime: attr::contains_name(&attrs, "panic_runtime"),
-            profiler_runtime: attr::contains_name(&attrs, "profiler_runtime"),
-            sanitizer_runtime: attr::contains_name(&attrs, "sanitizer_runtime"),
+            compiler_builtins: attr::contains_name(&attrs, sym::compiler_builtins),
+            needs_allocator: attr::contains_name(&attrs, sym::needs_allocator),
+            needs_panic_runtime: attr::contains_name(&attrs, sym::needs_panic_runtime),
+            no_builtins: attr::contains_name(&attrs, sym::no_builtins),
+            panic_runtime: attr::contains_name(&attrs, sym::panic_runtime),
+            profiler_runtime: attr::contains_name(&attrs, sym::profiler_runtime),
+            sanitizer_runtime: attr::contains_name(&attrs, sym::sanitizer_runtime),
 
             crate_deps,
             dylib_dependency_formats,
diff --git a/src/librustc_metadata/link_args.rs b/src/librustc_metadata/link_args.rs
index 6741b5235db..cd5951f0e0e 100644
--- a/src/librustc_metadata/link_args.rs
+++ b/src/librustc_metadata/link_args.rs
@@ -2,6 +2,7 @@ use rustc::hir::itemlikevisit::ItemLikeVisitor;
 use rustc::hir;
 use rustc::ty::TyCtxt;
 use rustc_target::spec::abi::Abi;
+use syntax::symbol::sym;
 
 pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Vec<String> {
     let mut collector = Collector {
@@ -37,7 +38,7 @@ impl<'tcx> ItemLikeVisitor<'tcx> for Collector {
         }
 
         // First, add all of the custom #[link_args] attributes
-        for m in it.attrs.iter().filter(|a| a.check_name("link_args")) {
+        for m in it.attrs.iter().filter(|a| a.check_name(sym::link_args)) {
             if let Some(linkarg) = m.value_str() {
                 self.add_link_args(&linkarg.as_str());
             }
diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs
index e0665127c0f..3e7e740a15c 100644
--- a/src/librustc_metadata/native_libs.rs
+++ b/src/librustc_metadata/native_libs.rs
@@ -8,7 +8,7 @@ use rustc_target::spec::abi::Abi;
 use syntax::attr;
 use syntax::source_map::Span;
 use syntax::feature_gate::{self, GateIssue};
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 use syntax::{span_err, struct_span_err};
 
 pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Vec<NativeLibrary> {
@@ -47,7 +47,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for Collector<'a, 'tcx> {
         }
 
         // Process all of the #[link(..)]-style arguments
-        for m in it.attrs.iter().filter(|a| a.check_name("link")) {
+        for m in it.attrs.iter().filter(|a| a.check_name(sym::link)) {
             let items = match m.meta_item_list() {
                 Some(item) => item,
                 None => continue,
@@ -62,7 +62,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for Collector<'a, 'tcx> {
             let mut kind_specified = false;
 
             for item in items.iter() {
-                if item.check_name("kind") {
+                if item.check_name(sym::kind) {
                     kind_specified = true;
                     let kind = match item.value_str() {
                         Some(name) => name,
@@ -81,9 +81,9 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for Collector<'a, 'tcx> {
                             cstore::NativeUnknown
                         }
                     };
-                } else if item.check_name("name") {
+                } else if item.check_name(sym::name) {
                     lib.name = item.value_str();
-                } else if item.check_name("cfg") {
+                } else if item.check_name(sym::cfg) {
                     let cfg = match item.meta_item_list() {
                         Some(list) => list,
                         None => continue, // skip like historical compilers
@@ -98,7 +98,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for Collector<'a, 'tcx> {
                     } else {
                         self.tcx.sess.span_err(cfg[0].span(), "invalid argument for `cfg(..)`");
                     }
-                } else if item.check_name("wasm_import_module") {
+                } else if item.check_name(sym::wasm_import_module) {
                     match item.value_str() {
                         Some(s) => lib.wasm_import_module = Some(s),
                         None => {
@@ -156,7 +156,7 @@ impl<'a, 'tcx> Collector<'a, 'tcx> {
         }
         if lib.cfg.is_some() && !self.tcx.features().link_cfg {
             feature_gate::emit_feature_err(&self.tcx.sess.parse_sess,
-                                           "link_cfg",
+                                           sym::link_cfg,
                                            span.unwrap(),
                                            GateIssue::Language,
                                            "is feature gated");
@@ -164,7 +164,7 @@ impl<'a, 'tcx> Collector<'a, 'tcx> {
         if lib.kind == cstore::NativeStaticNobundle &&
            !self.tcx.features().static_nobundle {
             feature_gate::emit_feature_err(&self.tcx.sess.parse_sess,
-                                           "static_nobundle",
+                                           sym::static_nobundle,
                                            span.unwrap_or_else(|| syntax_pos::DUMMY_SP),
                                            GateIssue::Language,
                                            "kind=\"static-nobundle\" is feature gated");
diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs
index 8aa6456ebe7..1068305a113 100644
--- a/src/librustc_mir/borrow_check/error_reporting.rs
+++ b/src/librustc_mir/borrow_check/error_reporting.rs
@@ -20,6 +20,7 @@ use rustc_data_structures::indexed_vec::Idx;
 use rustc_errors::{Applicability, DiagnosticBuilder};
 use syntax_pos::Span;
 use syntax::source_map::CompilerDesugaringKind;
+use syntax::symbol::sym;
 
 use super::borrow_set::BorrowData;
 use super::{MirBorrowckCtxt};
@@ -1839,7 +1840,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
             PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. })
         ) = place {
             let attrs = self.infcx.tcx.get_attrs(*def_id);
-            let is_thread_local = attrs.iter().any(|attr| attr.check_name("thread_local"));
+            let is_thread_local = attrs.iter().any(|attr| attr.check_name(sym::thread_local));
 
             debug!(
                 "is_place_thread_local: attrs={:?} is_thread_local={:?}",
diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs
index ad43c8ef66f..fa490c108c8 100644
--- a/src/librustc_mir/borrow_check/nll/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/mod.rs
@@ -20,6 +20,7 @@ use std::io;
 use std::path::PathBuf;
 use std::rc::Rc;
 use std::str::FromStr;
+use syntax::symbol::sym;
 
 use self::mir_util::PassWhere;
 use polonius_engine::{Algorithm, Output};
@@ -280,7 +281,7 @@ fn dump_annotation<'a, 'gcx, 'tcx>(
 ) {
     let tcx = infcx.tcx;
     let base_def_id = tcx.closure_base_def_id(mir_def_id);
-    if !tcx.has_attr(base_def_id, "rustc_regions") {
+    if !tcx.has_attr(base_def_id, sym::rustc_regions) {
         return;
     }
 
diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs
index 83221aca6c5..a9d23a0afea 100644
--- a/src/librustc_mir/dataflow/mod.rs
+++ b/src/librustc_mir/dataflow/mod.rs
@@ -1,4 +1,5 @@
 use syntax::ast::{self, MetaItem};
+use syntax::symbol::{Symbol, sym};
 
 use rustc_data_structures::bit_set::{BitSet, BitSetOperator, HybridBitSet};
 use rustc_data_structures::indexed_vec::Idx;
@@ -100,9 +101,9 @@ where
     fn propagate(&mut self) { self.flow_state.propagate(); }
 }
 
-pub(crate) fn has_rustc_mir_with(attrs: &[ast::Attribute], name: &str) -> Option<MetaItem> {
+pub(crate) fn has_rustc_mir_with(attrs: &[ast::Attribute], name: Symbol) -> Option<MetaItem> {
     for attr in attrs {
-        if attr.check_name("rustc_mir") {
+        if attr.check_name(sym::rustc_mir) {
             let items = attr.meta_item_list();
             for item in items.iter().flat_map(|l| l.iter()) {
                 match item.meta_item() {
@@ -158,10 +159,8 @@ impl<'a, 'gcx: 'tcx, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD> where BD: BitD
             return None;
         };
 
-        let print_preflow_to =
-            name_found(tcx.sess, attributes, "borrowck_graphviz_preflow");
-        let print_postflow_to =
-            name_found(tcx.sess, attributes, "borrowck_graphviz_postflow");
+        let print_preflow_to = name_found(tcx.sess, attributes, sym::borrowck_graphviz_preflow);
+        let print_postflow_to = name_found(tcx.sess, attributes, sym::borrowck_graphviz_postflow);
 
         let mut mbcx = DataflowBuilder {
             def_id,
diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs
index 7aed0bace8c..e8070b21bb8 100644
--- a/src/librustc_mir/hair/cx/mod.rs
+++ b/src/librustc_mir/hair/cx/mod.rs
@@ -16,7 +16,7 @@ use rustc::ty::subst::{Kind, InternalSubsts};
 use rustc::ty::layout::VariantIdx;
 use syntax::ast;
 use syntax::attr;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 use rustc::hir;
 use crate::hair::constant::{lit_to_const, LitToConstError};
 
@@ -67,7 +67,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
         // Some functions always have overflow checks enabled,
         // however, they may not get codegen'd, depending on
         // the settings for the crate they are codegened in.
-        let mut check_overflow = attr::contains_name(attrs, "rustc_inherit_overflow_checks");
+        let mut check_overflow = attr::contains_name(attrs, sym::rustc_inherit_overflow_checks);
 
         // Respect -C overflow-checks.
         check_overflow |= tcx.sess.overflow_checks();
diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs
index 01b1780a205..0576bb53d8f 100644
--- a/src/librustc_mir/hair/pattern/mod.rs
+++ b/src/librustc_mir/hair/pattern/mod.rs
@@ -27,6 +27,7 @@ use std::cmp::Ordering;
 use std::fmt;
 use syntax::ast;
 use syntax::ptr::P;
+use syntax::symbol::sym;
 use syntax_pos::Span;
 
 #[derive(Clone, Debug)]
@@ -978,7 +979,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
                 self.tcx.sess.span_err(span, "cannot use unions in constant patterns");
                 PatternKind::Wild
             }
-            ty::Adt(adt_def, _) if !self.tcx.has_attr(adt_def.did, "structural_match") => {
+            ty::Adt(adt_def, _) if !self.tcx.has_attr(adt_def.did, sym::structural_match) => {
                 let path = self.tcx.def_path_str(adt_def.did);
                 let msg = format!(
                     "to use a constant of type `{}` in a pattern, \
@@ -990,7 +991,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
                 PatternKind::Wild
             }
             ty::Ref(_, ty::TyS { sty: ty::Adt(adt_def, _), .. }, _)
-            if !self.tcx.has_attr(adt_def.did, "structural_match") => {
+            if !self.tcx.has_attr(adt_def.did, sym::structural_match) => {
                 // HACK(estebank): Side-step ICE #53708, but anything other than erroring here
                 // would be wrong. Returnging `PatternKind::Wild` is not technically correct.
                 let path = self.tcx.def_path_str(adt_def.did);
diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs
index 58e474658ea..2512525b4bb 100644
--- a/src/librustc_mir/interpret/cast.rs
+++ b/src/librustc_mir/interpret/cast.rs
@@ -2,6 +2,7 @@ use rustc::ty::{self, Ty, TypeAndMut};
 use rustc::ty::layout::{self, TyLayout, Size};
 use rustc::ty::adjustment::{PointerCast};
 use syntax::ast::{FloatTy, IntTy, UintTy};
+use syntax::symbol::sym;
 
 use rustc_apfloat::ieee::{Single, Double};
 use rustc::mir::interpret::{
@@ -76,9 +77,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
                 // The src operand does not matter, just its type
                 match src.layout.ty.sty {
                     ty::FnDef(def_id, substs) => {
-                        if self.tcx.has_attr(def_id, "rustc_args_required_const") {
-                            bug!("reifying a fn ptr that requires \
-                                    const arguments");
+                        if self.tcx.has_attr(def_id, sym::rustc_args_required_const) {
+                            bug!("reifying a fn ptr that requires const arguments");
                         }
                         let instance: EvalResult<'tcx, _> = ty::Instance::resolve(
                             *self.tcx,
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index 078b347fb3f..fab07a2290e 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -12,7 +12,7 @@ use rustc::lint::builtin::{SAFE_EXTERN_STATICS, SAFE_PACKED_BORROWS, UNUSED_UNSA
 use rustc::mir::*;
 use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext};
 
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 
 use std::ops::Bound;
 
@@ -612,7 +612,7 @@ fn report_unused_unsafe(tcx: TyCtxt<'_, '_, '_>,
 fn builtin_derive_def_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Option<DefId> {
     debug!("builtin_derive_def_id({:?})", def_id);
     if let Some(impl_def_id) = tcx.impl_of_method(def_id) {
-        if tcx.has_attr(impl_def_id, "automatically_derived") {
+        if tcx.has_attr(impl_def_id, sym::automatically_derived) {
             debug!("builtin_derive_def_id({:?}) - is {:?}", def_id, impl_def_id);
             Some(impl_def_id)
         } else {
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 9a39e071721..579f75ba516 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -22,6 +22,7 @@ use rustc::middle::lang_items;
 use rustc::session::config::nightly_options;
 use syntax::ast::LitKind;
 use syntax::feature_gate::{emit_feature_err, GateIssue};
+use syntax::symbol::sym;
 use syntax_pos::{Span, DUMMY_SP};
 
 use std::fmt;
@@ -380,8 +381,8 @@ impl Qualif for IsNotPromotable {
 
                 !allowed ||
                     cx.tcx.get_attrs(def_id).iter().any(
-                        |attr| attr.check_name("thread_local"
-                    ))
+                        |attr| attr.check_name(sym::thread_local)
+                    )
             }
         }
     }
@@ -939,7 +940,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
                 if self.tcx
                        .get_attrs(def_id)
                        .iter()
-                       .any(|attr| attr.check_name("thread_local")) {
+                       .any(|attr| attr.check_name(sym::thread_local)) {
                     if self.mode != Mode::Fn {
                         span_err!(self.tcx.sess, self.span, E0625,
                                   "thread-local statics cannot be \
@@ -994,7 +995,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
                                 if let ty::RawPtr(_) = base_ty.sty {
                                     if !self.tcx.features().const_raw_ptr_deref {
                                         emit_feature_err(
-                                            &self.tcx.sess.parse_sess, "const_raw_ptr_deref",
+                                            &self.tcx.sess.parse_sess, sym::const_raw_ptr_deref,
                                             self.span, GateIssue::Language,
                                             &format!(
                                                 "dereferencing raw pointers in {}s is unstable",
@@ -1018,7 +1019,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
                                     Mode::ConstFn => {
                                         if !self.tcx.features().const_fn_union {
                                             emit_feature_err(
-                                                &self.tcx.sess.parse_sess, "const_fn_union",
+                                                &self.tcx.sess.parse_sess, sym::const_fn_union,
                                                 self.span, GateIssue::Language,
                                                 "unions in const fn are unstable",
                                             );
@@ -1123,7 +1124,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
                             // in const fn and constants require the feature gate
                             // FIXME: make it unsafe inside const fn and constants
                             emit_feature_err(
-                                &self.tcx.sess.parse_sess, "const_raw_ptr_to_usize_cast",
+                                &self.tcx.sess.parse_sess, sym::const_raw_ptr_to_usize_cast,
                                 self.span, GateIssue::Language,
                                 &format!(
                                     "casting pointers to integers in {}s is unstable",
@@ -1149,7 +1150,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
                         // FIXME: make it unsafe to use these operations
                         emit_feature_err(
                             &self.tcx.sess.parse_sess,
-                            "const_compare_raw_pointers",
+                            sym::const_compare_raw_pointers,
                             self.span,
                             GateIssue::Language,
                             &format!("comparing raw pointers inside {}", self.mode),
@@ -1210,7 +1211,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
                                         // const eval transmute calls only with the feature gate
                                         if !self.tcx.features().const_transmute {
                                             emit_feature_err(
-                                                &self.tcx.sess.parse_sess, "const_transmute",
+                                                &self.tcx.sess.parse_sess, sym::const_transmute,
                                                 self.span, GateIssue::Language,
                                                 &format!("The use of std::mem::transmute() \
                                                 is gated in {}s", self.mode));
@@ -1249,7 +1250,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
                                         // Don't allow panics in constants without the feature gate.
                                         emit_feature_err(
                                             &self.tcx.sess.parse_sess,
-                                            "const_panic",
+                                            sym::const_panic,
                                             self.span,
                                             GateIssue::Language,
                                             &format!("panicking in {}s is unstable", self.mode),
@@ -1260,7 +1261,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
                                     // Check `#[unstable]` const fns or `#[rustc_const_unstable]`
                                     // functions without the feature gate active in this crate in
                                     // order to report a better error message than the one below.
-                                    if !self.span.allows_unstable(&feature.as_str()) {
+                                    if !self.span.allows_unstable(feature) {
                                         let mut err = self.tcx.sess.struct_span_err(self.span,
                                             &format!("`{}` is not yet stable as a const fn",
                                                     self.tcx.def_path_str(def_id)));
@@ -1592,7 +1593,7 @@ impl MirPass for QualifyAndPromoteConstants {
         if mode == Mode::Static {
             // `#[thread_local]` statics don't have to be `Sync`.
             for attr in &tcx.get_attrs(def_id)[..] {
-                if attr.check_name("thread_local") {
+                if attr.check_name(sym::thread_local) {
                     return;
                 }
             }
@@ -1616,7 +1617,7 @@ impl MirPass for QualifyAndPromoteConstants {
 
 fn args_required_const(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Option<FxHashSet<usize>> {
     let attrs = tcx.get_attrs(def_id);
-    let attr = attrs.iter().find(|a| a.check_name("rustc_args_required_const"))?;
+    let attr = attrs.iter().find(|a| a.check_name(sym::rustc_args_required_const))?;
     let mut ret = FxHashSet::default();
     for meta in attr.meta_item_list()? {
         match meta.literal()?.node {
diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs
index 246f876235d..815821f6ff0 100644
--- a/src/librustc_mir/transform/rustc_peek.rs
+++ b/src/librustc_mir/transform/rustc_peek.rs
@@ -1,5 +1,6 @@
 use rustc_target::spec::abi::{Abi};
 use syntax::ast;
+use syntax::symbol::sym;
 use syntax_pos::Span;
 
 use rustc::ty::{self, TyCtxt};
@@ -27,7 +28,7 @@ impl MirPass for SanityCheck {
     fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
                           src: MirSource<'tcx>, mir: &mut Mir<'tcx>) {
         let def_id = src.def_id();
-        if !tcx.has_attr(def_id, "rustc_mir") {
+        if !tcx.has_attr(def_id, sym::rustc_mir) {
             debug!("skipping rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id));
             return;
         } else {
@@ -52,16 +53,16 @@ impl MirPass for SanityCheck {
                         DefinitelyInitializedPlaces::new(tcx, mir, &mdpe),
                         |bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]));
 
-        if has_rustc_mir_with(&attributes, "rustc_peek_maybe_init").is_some() {
+        if has_rustc_mir_with(&attributes, sym::rustc_peek_maybe_init).is_some() {
             sanity_check_via_rustc_peek(tcx, mir, def_id, &attributes, &flow_inits);
         }
-        if has_rustc_mir_with(&attributes, "rustc_peek_maybe_uninit").is_some() {
+        if has_rustc_mir_with(&attributes, sym::rustc_peek_maybe_uninit).is_some() {
             sanity_check_via_rustc_peek(tcx, mir, def_id, &attributes, &flow_uninits);
         }
-        if has_rustc_mir_with(&attributes, "rustc_peek_definite_init").is_some() {
+        if has_rustc_mir_with(&attributes, sym::rustc_peek_definite_init).is_some() {
             sanity_check_via_rustc_peek(tcx, mir, def_id, &attributes, &flow_def_inits);
         }
-        if has_rustc_mir_with(&attributes, "stop_after_dataflow").is_some() {
+        if has_rustc_mir_with(&attributes, sym::stop_after_dataflow).is_some() {
             tcx.sess.fatal("stop_after_dataflow ended compilation");
         }
     }
diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs
index 6cb3161382a..7adf0af31c6 100644
--- a/src/librustc_passes/ast_validation.rs
+++ b/src/librustc_passes/ast_validation.rs
@@ -15,7 +15,7 @@ use rustc_data_structures::fx::FxHashMap;
 use syntax::ast::*;
 use syntax::attr;
 use syntax::source_map::Spanned;
-use syntax::symbol::keywords;
+use syntax::symbol::{keywords, sym};
 use syntax::ptr::P;
 use syntax::visit::{self, Visitor};
 use syntax::{span_err, struct_span_err, walk_list};
@@ -565,7 +565,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
             self.has_proc_macro_decls = true;
         }
 
-        if attr::contains_name(&item.attrs, "global_allocator") {
+        if attr::contains_name(&item.attrs, sym::global_allocator) {
             self.has_global_allocator = true;
         }
 
@@ -676,8 +676,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
             }
             ItemKind::Mod(_) => {
                 // Ensure that `path` attributes on modules are recorded as used (cf. issue #35584).
-                attr::first_attr_value_str_by_name(&item.attrs, "path");
-                if attr::contains_name(&item.attrs, "warn_directory_ownership") {
+                attr::first_attr_value_str_by_name(&item.attrs, sym::path);
+                if attr::contains_name(&item.attrs, sym::warn_directory_ownership) {
                     let lint = lint::builtin::LEGACY_DIRECTORY_OWNERSHIP;
                     let msg = "cannot declare a new module at this location";
                     self.session.buffer_lint(lint, item.id, item.span, msg);
diff --git a/src/librustc_passes/layout_test.rs b/src/librustc_passes/layout_test.rs
index 7041a5593ab..c865845b5e3 100644
--- a/src/librustc_passes/layout_test.rs
+++ b/src/librustc_passes/layout_test.rs
@@ -12,6 +12,7 @@ use rustc::ty::ParamEnv;
 use rustc::ty::Ty;
 use rustc::ty::TyCtxt;
 use syntax::ast::Attribute;
+use syntax::symbol::sym;
 
 pub fn test_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     if tcx.features().rustc_attrs {
@@ -32,7 +33,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for VarianceTest<'a, 'tcx> {
 
         if let ItemKind::Ty(..) = item.node {
             for attr in self.tcx.get_attrs(item_def_id).iter() {
-                if attr.check_name("rustc_layout") {
+                if attr.check_name(sym::rustc_layout) {
                     self.dump_layout_of(item_def_id, item, attr);
                 }
             }
diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs
index 2d35a0de795..37917aaa4a8 100644
--- a/src/librustc_passes/rvalue_promotion.rs
+++ b/src/librustc_passes/rvalue_promotion.rs
@@ -25,6 +25,7 @@ use rustc::ty::query::Providers;
 use rustc::ty::subst::{InternalSubsts, SubstsRef};
 use rustc::util::nodemap::{ItemLocalSet, HirIdSet};
 use rustc::hir;
+use syntax::symbol::sym;
 use syntax_pos::{Span, DUMMY_SP};
 use log::debug;
 use Promotability::*;
@@ -335,7 +336,7 @@ fn check_expr_kind<'a, 'tcx>(
 
                     if v.in_static {
                         for attr in &v.tcx.get_attrs(did)[..] {
-                            if attr.check_name("thread_local") {
+                            if attr.check_name(sym::thread_local) {
                                 debug!("Reference to Static(id={:?}) is unpromotable \
                                        due to a #[thread_local] attribute", did);
                                 return NotPromotable;
diff --git a/src/librustc_plugin/build.rs b/src/librustc_plugin/build.rs
index 31018a7cd7a..8259419c64a 100644
--- a/src/librustc_plugin/build.rs
+++ b/src/librustc_plugin/build.rs
@@ -1,6 +1,7 @@
 //! Used by `rustc` when compiling a plugin crate.
 
 use syntax::attr;
+use syntax::symbol::sym;
 use syntax_pos::Span;
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
 use rustc::hir;
@@ -15,8 +16,7 @@ struct RegistrarFinder {
 impl<'v> ItemLikeVisitor<'v> for RegistrarFinder {
     fn visit_item(&mut self, item: &hir::Item) {
         if let hir::ItemKind::Fn(..) = item.node {
-            if attr::contains_name(&item.attrs,
-                                   "plugin_registrar") {
+            if attr::contains_name(&item.attrs, sym::plugin_registrar) {
                 self.registrars.push((item.hir_id, item.span));
             }
         }
diff --git a/src/librustc_plugin/load.rs b/src/librustc_plugin/load.rs
index 8b86bddb29f..43eddbb653f 100644
--- a/src/librustc_plugin/load.rs
+++ b/src/librustc_plugin/load.rs
@@ -11,6 +11,7 @@ use std::mem;
 use std::path::PathBuf;
 use syntax::ast;
 use syntax::span_err;
+use syntax::symbol::sym;
 use syntax_pos::{Span, DUMMY_SP};
 
 /// Pointer to a registrar function.
@@ -45,7 +46,7 @@ pub fn load_plugins(sess: &Session,
     // the feature enabled will result in an error later...
     if sess.features_untracked().plugin {
         for attr in &krate.attrs {
-            if !attr.check_name("plugin") {
+            if !attr.check_name(sym::plugin) {
                 continue;
             }
 
diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs
index 5c5b6f232b2..913657b2934 100644
--- a/src/librustc_plugin/registry.rs
+++ b/src/librustc_plugin/registry.rs
@@ -49,7 +49,7 @@ pub struct Registry<'a> {
     pub llvm_passes: Vec<String>,
 
     #[doc(hidden)]
-    pub attributes: Vec<(String, AttributeType)>,
+    pub attributes: Vec<(Symbol, AttributeType)>,
 }
 
 impl<'a> Registry<'a> {
@@ -169,7 +169,7 @@ impl<'a> Registry<'a> {
     /// Registered attributes will bypass the `custom_attribute` feature gate.
     /// `Whitelisted` attributes will additionally not trigger the `unused_attribute`
     /// lint. `CrateLevel` attributes will not be allowed on anything other than a crate.
-    pub fn register_attribute(&mut self, name: String, ty: AttributeType) {
+    pub fn register_attribute(&mut self, name: Symbol, ty: AttributeType) {
         self.attributes.push((name, ty));
     }
 }
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index e561b387389..cd21713cddf 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -27,7 +27,7 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::sync::Lrc;
 use syntax::ast::Ident;
 use syntax::attr;
-use syntax::symbol::keywords;
+use syntax::symbol::{keywords, sym};
 use syntax_pos::Span;
 
 use std::{cmp, fmt, mem};
@@ -260,7 +260,8 @@ fn def_id_visibility<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
                                 ctor_vis = ty::Visibility::Restricted(
                                     DefId::local(CRATE_DEF_INDEX));
                                 let attrs = tcx.get_attrs(variant.def_id);
-                                span = attr::find_by_name(&attrs, "non_exhaustive").unwrap().span;
+                                span = attr::find_by_name(&attrs, sym::non_exhaustive)
+                                    .unwrap().span;
                                 descr = "crate-visible";
                             }
 
@@ -291,7 +292,7 @@ fn def_id_visibility<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
                                 if adt_def.non_enum_variant().is_field_list_non_exhaustive() {
                                     ctor_vis =
                                         ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX));
-                                    span = attr::find_by_name(&item.attrs, "non_exhaustive")
+                                    span = attr::find_by_name(&item.attrs, sym::non_exhaustive)
                                                 .unwrap().span;
                                     descr = "crate-visible";
                                 }
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 3c5760c746f..cf09e31bb62 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -37,7 +37,7 @@ use syntax::feature_gate::is_builtin_attr;
 use syntax::parse::token::{self, Token};
 use syntax::span_err;
 use syntax::std_inject::injected_crate_name;
-use syntax::symbol::keywords;
+use syntax::symbol::{keywords, sym};
 use syntax::visit::{self, Visitor};
 
 use syntax_pos::{Span, DUMMY_SP};
@@ -257,7 +257,7 @@ impl<'a> Resolver<'a> {
             }
             ast::UseTreeKind::Glob => {
                 let subclass = GlobImport {
-                    is_prelude: attr::contains_name(&item.attrs, "prelude_import"),
+                    is_prelude: attr::contains_name(&item.attrs, sym::prelude_import),
                     max_vis: Cell::new(ty::Visibility::Invisible),
                 };
                 self.add_import_directive(
@@ -427,7 +427,7 @@ impl<'a> Resolver<'a> {
                 let module_kind = ModuleKind::Def(DefKind::Mod, def_id, ident.name);
                 let module = self.arenas.alloc_module(ModuleData {
                     no_implicit_prelude: parent.no_implicit_prelude || {
-                        attr::contains_name(&item.attrs, "no_implicit_prelude")
+                        attr::contains_name(&item.attrs, sym::no_implicit_prelude)
                     },
                     ..ModuleData::new(Some(parent), module_kind, def_id, expansion, item.span)
                 });
@@ -456,12 +456,12 @@ impl<'a> Resolver<'a> {
 
                 // Functions introducing procedural macros reserve a slot
                 // in the macro namespace as well (see #52225).
-                if attr::contains_name(&item.attrs, "proc_macro") ||
-                   attr::contains_name(&item.attrs, "proc_macro_attribute") {
+                if attr::contains_name(&item.attrs, sym::proc_macro) ||
+                   attr::contains_name(&item.attrs, sym::proc_macro_attribute) {
                     let res = Res::Def(DefKind::Macro(MacroKind::ProcMacroStub), res.def_id());
                     self.define(parent, ident, MacroNS, (res, vis, sp, expansion));
                 }
-                if let Some(attr) = attr::find_by_name(&item.attrs, "proc_macro_derive") {
+                if let Some(attr) = attr::find_by_name(&item.attrs, sym::proc_macro_derive) {
                     if let Some(trait_attr) =
                             attr.meta_item_list().and_then(|list| list.get(0).cloned()) {
                         if let Some(ident) = trait_attr.ident() {
@@ -518,7 +518,7 @@ impl<'a> Resolver<'a> {
 
                 let mut ctor_vis = vis;
 
-                let has_non_exhaustive = attr::contains_name(&item.attrs, "non_exhaustive");
+                let has_non_exhaustive = attr::contains_name(&item.attrs, sym::non_exhaustive);
 
                 // If the structure is marked as non_exhaustive then lower the visibility
                 // to within the crate.
@@ -599,7 +599,7 @@ impl<'a> Resolver<'a> {
         // If the variant is marked as non_exhaustive then lower the visibility to within the
         // crate.
         let mut ctor_vis = vis;
-        let has_non_exhaustive = attr::contains_name(&variant.node.attrs, "non_exhaustive");
+        let has_non_exhaustive = attr::contains_name(&variant.node.attrs, sym::non_exhaustive);
         if has_non_exhaustive && vis == ty::Visibility::Public {
             ctor_vis = ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX));
         }
@@ -825,7 +825,7 @@ impl<'a> Resolver<'a> {
         let mut import_all = None;
         let mut single_imports = Vec::new();
         for attr in &item.attrs {
-            if attr.check_name("macro_use") {
+            if attr.check_name(sym::macro_use) {
                 if self.current_module.parent.is_some() {
                     span_err!(self.session, item.span, E0468,
                         "an `extern crate` loading macros must be at the crate root");
@@ -908,7 +908,7 @@ impl<'a> Resolver<'a> {
     /// Returns `true` if this attribute list contains `macro_use`.
     fn contains_macro_use(&mut self, attrs: &[ast::Attribute]) -> bool {
         for attr in attrs {
-            if attr.check_name("macro_escape") {
+            if attr.check_name(sym::macro_escape) {
                 let msg = "macro_escape is a deprecated synonym for macro_use";
                 let mut err = self.session.struct_span_warn(attr.span, msg);
                 if let ast::AttrStyle::Inner = attr.style {
@@ -916,7 +916,7 @@ impl<'a> Resolver<'a> {
                 } else {
                     err.emit();
                 }
-            } else if !attr.check_name("macro_use") {
+            } else if !attr.check_name(sym::macro_use) {
                 continue;
             }
 
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 18da89b9099..0dd6f378730 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -43,7 +43,7 @@ use syntax::ast::{self, Name, NodeId, Ident, FloatTy, IntTy, UintTy};
 use syntax::ext::base::SyntaxExtension;
 use syntax::ext::base::Determinacy::{self, Determined, Undetermined};
 use syntax::ext::base::MacroKind;
-use syntax::symbol::{Symbol, keywords};
+use syntax::symbol::{Symbol, keywords, sym};
 use syntax::util::lev_distance::find_best_match_for_name;
 
 use syntax::visit::{self, FnKind, Visitor};
@@ -1964,7 +1964,7 @@ impl<'a> Resolver<'a> {
             keywords::Invalid.name(),
         );
         let graph_root = arenas.alloc_module(ModuleData {
-            no_implicit_prelude: attr::contains_name(&krate.attrs, "no_implicit_prelude"),
+            no_implicit_prelude: attr::contains_name(&krate.attrs, sym::no_implicit_prelude),
             ..ModuleData::new(None, root_module_kind, root_def_id, Mark::root(), krate.span)
         });
         let mut module_map = FxHashMap::default();
@@ -1978,9 +1978,9 @@ impl<'a> Resolver<'a> {
             session.opts.externs.iter().map(|kv| (Ident::from_str(kv.0), Default::default()))
                                        .collect();
 
-        if !attr::contains_name(&krate.attrs, "no_core") {
+        if !attr::contains_name(&krate.attrs, sym::no_core) {
             extern_prelude.insert(Ident::from_str("core"), Default::default());
-            if !attr::contains_name(&krate.attrs, "no_std") {
+            if !attr::contains_name(&krate.attrs, sym::no_std) {
                 extern_prelude.insert(Ident::from_str("std"), Default::default());
                 if session.rust_2018() {
                     extern_prelude.insert(Ident::from_str("meta"), Default::default());
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 79a92d595c2..62f2768888a 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -22,7 +22,7 @@ use syntax::ext::tt::macro_rules;
 use syntax::feature_gate::{
     feature_err, is_builtin_attr_name, AttributeGate, GateIssue, Stability, BUILTIN_ATTRIBUTES,
 };
-use syntax::symbol::{Symbol, keywords};
+use syntax::symbol::{Symbol, keywords, sym};
 use syntax::visit::Visitor;
 use syntax::util::lev_distance::find_best_match_for_name;
 use syntax_pos::{Span, DUMMY_SP};
@@ -313,7 +313,8 @@ impl<'a> Resolver<'a> {
                             if !features.rustc_attrs {
                                 let msg = "unless otherwise specified, attributes with the prefix \
                                            `rustc_` are reserved for internal compiler diagnostics";
-                                self.report_unknown_attribute(path.span, &name, msg, "rustc_attrs");
+                                self.report_unknown_attribute(path.span, &name, msg,
+                                                              sym::rustc_attrs);
                             }
                         } else if !features.custom_attribute {
                             let msg = format!("The attribute `{}` is currently unknown to the \
@@ -323,7 +324,7 @@ impl<'a> Resolver<'a> {
                                 path.span,
                                 &name,
                                 &msg,
-                                "custom_attribute",
+                                sym::custom_attribute,
                             );
                         }
                     }
@@ -345,7 +346,7 @@ impl<'a> Resolver<'a> {
         Ok((res, self.get_macro(res)))
     }
 
-    fn report_unknown_attribute(&self, span: Span, name: &str, msg: &str, feature: &str) {
+    fn report_unknown_attribute(&self, span: Span, name: &str, msg: &str, feature: Symbol) {
         let mut err = feature_err(
             &self.session.parse_sess,
             feature,
@@ -693,7 +694,7 @@ impl<'a> Resolver<'a> {
                 WhereToResolve::LegacyPluginHelpers => {
                     if (use_prelude || rust_2015) &&
                        self.session.plugin_attributes.borrow().iter()
-                                                     .any(|(name, _)| ident.name == &**name) {
+                                                     .any(|(name, _)| ident.name == *name) {
                         let binding = (Res::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper),
                                        ty::Visibility::Public, DUMMY_SP, Mark::root())
                                        .to_name_binding(self.arenas);
@@ -1106,7 +1107,7 @@ impl<'a> Resolver<'a> {
             let ident = ident.modern();
             self.macro_names.insert(ident);
             let res = Res::Def(DefKind::Macro(MacroKind::Bang), def_id);
-            let is_macro_export = attr::contains_name(&item.attrs, "macro_export");
+            let is_macro_export = attr::contains_name(&item.attrs, sym::macro_export);
             let vis = if is_macro_export {
                 ty::Visibility::Public
             } else {
@@ -1124,7 +1125,7 @@ impl<'a> Resolver<'a> {
                 self.define(module, ident, MacroNS,
                             (res, vis, item.span, expansion, IsMacroExport));
             } else {
-                if !attr::contains_name(&item.attrs, "rustc_doc_only_macro") {
+                if !attr::contains_name(&item.attrs, sym::rustc_doc_only_macro) {
                     self.check_reserved_macro_name(ident, MacroNS);
                 }
                 self.unused_macros.insert(def_id);
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index f3e0fb32ec2..cb2454aa4b5 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -879,7 +879,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
         let mut result = String::new();
 
         for attr in attrs {
-            if attr.check_name("doc") {
+            if attr.check_name(sym::doc) {
                 if let Some(val) = attr.value_str() {
                     if attr.is_sugared_doc {
                         result.push_str(&strip_doc_comment_decoration(&val.as_str()));
@@ -889,10 +889,10 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                     result.push('\n');
                 } else if let Some(meta_list) = attr.meta_item_list() {
                     meta_list.into_iter()
-                             .filter(|it| it.check_name("include"))
+                             .filter(|it| it.check_name(sym::include))
                              .filter_map(|it| it.meta_item_list().map(|l| l.to_owned()))
                              .flat_map(|it| it)
-                             .filter(|meta| meta.check_name("contents"))
+                             .filter(|meta| meta.check_name(sym::contents))
                              .filter_map(|meta| meta.value_str())
                              .for_each(|val| {
                                  result.push_str(&val.as_str());
diff --git a/src/librustc_traits/lowering/mod.rs b/src/librustc_traits/lowering/mod.rs
index 50c21302632..580b1571e52 100644
--- a/src/librustc_traits/lowering/mod.rs
+++ b/src/librustc_traits/lowering/mod.rs
@@ -21,6 +21,7 @@ use rustc::ty::query::Providers;
 use rustc::ty::{self, List, TyCtxt};
 use rustc::ty::subst::{Subst, InternalSubsts};
 use syntax::ast;
+use syntax::symbol::sym;
 
 use std::iter;
 
@@ -640,11 +641,11 @@ impl<'a, 'tcx> ClauseDumper<'a, 'tcx> {
         for attr in attrs {
             let mut clauses = None;
 
-            if attr.check_name("rustc_dump_program_clauses") {
+            if attr.check_name(sym::rustc_dump_program_clauses) {
                 clauses = Some(self.tcx.program_clauses_for(def_id));
             }
 
-            if attr.check_name("rustc_dump_env_program_clauses") {
+            if attr.check_name(sym::rustc_dump_env_program_clauses) {
                 let environment = self.tcx.environment(def_id);
                 clauses = Some(self.tcx.program_clauses_for_env(environment));
             }
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index da47ccf38a0..caefe124211 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -25,6 +25,7 @@ use syntax::ast;
 use syntax::feature_gate::{GateIssue, emit_feature_err};
 use syntax::ptr::P;
 use syntax::util::lev_distance::find_best_match_for_name;
+use syntax::symbol::sym;
 use syntax_pos::{DUMMY_SP, Span, MultiSpan};
 use crate::util::common::ErrorReported;
 use crate::util::nodemap::FxHashMap;
@@ -802,7 +803,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
             } else {
                 "parenthetical notation is only stable when used with `Fn`-family traits"
             };
-            emit_feature_err(&self.tcx().sess.parse_sess, "unboxed_closures",
+            emit_feature_err(&self.tcx().sess.parse_sess, sym::unboxed_closures,
                              span, GateIssue::Language, msg);
         }
 
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index 008975068e5..90b2643d165 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -68,6 +68,7 @@ use smallvec::{smallvec, SmallVec};
 use std::ops::Deref;
 use syntax::feature_gate;
 use syntax::ptr::P;
+use syntax::symbol::sym;
 use syntax_pos;
 
 struct Coerce<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
@@ -620,7 +621,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
 
         if has_unsized_tuple_coercion && !self.tcx.features().unsized_tuple_coercion {
             feature_gate::emit_feature_err(&self.tcx.sess.parse_sess,
-                                           "unsized_tuple_coercion",
+                                           sym::unsized_tuple_coercion,
                                            self.cause.span,
                                            feature_gate::GateIssue::Language,
                                            feature_gate::EXPLAIN_UNSIZED_TUPLE_COERCION);
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index 1699447886a..8d68179b495 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -2,6 +2,7 @@ use crate::check::FnCtxt;
 use rustc::infer::InferOk;
 use rustc::traits::{self, ObligationCause, ObligationCauseCode};
 
+use syntax::symbol::sym;
 use syntax::util::parser::PREC_POSTFIX;
 use syntax_pos::Span;
 use rustc::hir;
@@ -197,7 +198,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 //
                 // FIXME? Other potential candidate methods: `as_ref` and
                 // `as_mut`?
-                .find(|a| a.check_name("rustc_conversion_suggestion")).is_some()
+                .find(|a| a.check_name(sym::rustc_conversion_suggestion)).is_some()
         });
 
         methods
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index dc73ada1506..a184a2daeb6 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -123,7 +123,7 @@ use syntax::attr;
 use syntax::feature_gate::{GateIssue, emit_feature_err};
 use syntax::ptr::P;
 use syntax::source_map::{DUMMY_SP, original_sp};
-use syntax::symbol::{Symbol, LocalInternedString, keywords};
+use syntax::symbol::{Symbol, LocalInternedString, keywords, sym};
 use syntax::util::lev_distance::find_best_match_for_name;
 
 use std::cell::{Cell, RefCell, Ref, RefMut};
@@ -1840,7 +1840,7 @@ pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
     if vs.is_empty() {
         let attributes = tcx.get_attrs(def_id);
-        if let Some(attr) = attr::find_by_name(&attributes, "repr") {
+        if let Some(attr) = attr::find_by_name(&attributes, sym::repr) {
             struct_span_err!(
                 tcx.sess, attr.span, E0084,
                 "unsupported representation for zero-variant enum")
@@ -1853,7 +1853,7 @@ pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
         if !tcx.features().repr128 {
             emit_feature_err(&tcx.sess.parse_sess,
-                             "repr128",
+                             sym::repr128,
                              sp,
                              GateIssue::Language,
                              "repr with 128-bit type is unstable");
@@ -5499,7 +5499,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                                       span: Span) {
         // We're only interested in functions tagged with
         // #[rustc_args_required_const], so ignore anything that's not.
-        if !self.tcx.has_attr(def_id, "rustc_args_required_const") {
+        if !self.tcx.has_attr(def_id, sym::rustc_args_required_const) {
             return
         }
 
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index fd7d6fe694c..b009c8ea6dc 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -13,6 +13,7 @@ use rustc::infer::opaque_types::may_define_existential_type;
 use syntax::ast;
 use syntax::feature_gate::{self, GateIssue};
 use syntax_pos::Span;
+use syntax::symbol::sym;
 use errors::{DiagnosticBuilder, DiagnosticId};
 
 use rustc::hir::itemlikevisit::ParItemLikeVisitor;
@@ -796,7 +797,7 @@ fn check_method_receiver<'fcx, 'gcx, 'tcx>(fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
                 // report error, would have worked with arbitrary_self_types
                 feature_gate::feature_err(
                     &fcx.tcx.sess.parse_sess,
-                    "arbitrary_self_types",
+                    sym::arbitrary_self_types,
                     span,
                     GateIssue::Language,
                     &format!(
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs
index bf978352fae..ecb8e09ec24 100644
--- a/src/librustc_typeck/check/writeback.rs
+++ b/src/librustc_typeck/check/writeback.rs
@@ -16,6 +16,7 @@ use rustc::mir::interpret::ConstValue;
 use rustc::util::nodemap::DefIdSet;
 use rustc_data_structures::sync::Lrc;
 use std::mem;
+use syntax::symbol::sym;
 use syntax_pos::Span;
 
 ///////////////////////////////////////////////////////////////////////////
@@ -36,8 +37,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         let item_def_id = self.tcx.hir().local_def_id(item_id);
 
         // This attribute causes us to dump some writeback information
-        // in the form of errors, which is used for unit tests.
-        let rustc_dump_user_substs = self.tcx.has_attr(item_def_id, "rustc_dump_user_substs");
+        // in the form of errors, which is uSymbolfor unit tests.
+        let rustc_dump_user_substs = self.tcx.has_attr(item_def_id, sym::rustc_dump_user_substs);
 
         let mut wbcx = WritebackCx::new(self, body, rustc_dump_user_substs);
         for arg in &body.arguments {
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 4185999fdd6..29b47089409 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -39,7 +39,7 @@ use syntax::ast::{Ident, MetaItemKind};
 use syntax::attr::{InlineAttr, OptimizeAttr, list_contains_name, mark_used};
 use syntax::source_map::Spanned;
 use syntax::feature_gate;
-use syntax::symbol::{keywords, Symbol};
+use syntax::symbol::{keywords, Symbol, sym};
 use syntax_pos::{Span, DUMMY_SP};
 
 use rustc::hir::def::{CtorKind, Res, DefKind};
@@ -750,7 +750,7 @@ fn trait_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::
         _ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"),
     };
 
-    let paren_sugar = tcx.has_attr(def_id, "rustc_paren_sugar");
+    let paren_sugar = tcx.has_attr(def_id, sym::rustc_paren_sugar);
     if paren_sugar && !tcx.features().unboxed_closures {
         let mut err = tcx.sess.struct_span_err(
             item.span,
@@ -765,7 +765,7 @@ fn trait_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::
         err.emit();
     }
 
-    let is_marker = tcx.has_attr(def_id, "marker");
+    let is_marker = tcx.has_attr(def_id, sym::marker);
     let def_path_hash = tcx.def_path_hash(def_id);
     let def = ty::TraitDef::new(def_id, unsafety, paren_sugar, is_auto, is_marker, def_path_hash);
     tcx.alloc_trait_def(def)
@@ -2382,7 +2382,7 @@ fn from_target_feature(
     tcx: TyCtxt<'_, '_, '_>,
     id: DefId,
     attr: &ast::Attribute,
-    whitelist: &FxHashMap<String, Option<String>>,
+    whitelist: &FxHashMap<String, Option<Symbol>>,
     target_features: &mut Vec<Symbol>,
 ) {
     let list = match attr.meta_item_list() {
@@ -2392,7 +2392,7 @@ fn from_target_feature(
     let rust_features = tcx.features();
     for item in list {
         // Only `enable = ...` is accepted in the meta item list
-        if !item.check_name("enable") {
+        if !item.check_name(sym::enable) {
             let msg = "#[target_feature(..)] only accepts sub-keys of `enable` \
                        currently";
             tcx.sess.span_err(item.span(), &msg);
@@ -2435,29 +2435,29 @@ fn from_target_feature(
             };
 
             // Only allow features whose feature gates have been enabled
-            let allowed = match feature_gate.as_ref().map(|s| &**s) {
-                Some("arm_target_feature") => rust_features.arm_target_feature,
-                Some("aarch64_target_feature") => rust_features.aarch64_target_feature,
-                Some("hexagon_target_feature") => rust_features.hexagon_target_feature,
-                Some("powerpc_target_feature") => rust_features.powerpc_target_feature,
-                Some("mips_target_feature") => rust_features.mips_target_feature,
-                Some("avx512_target_feature") => rust_features.avx512_target_feature,
-                Some("mmx_target_feature") => rust_features.mmx_target_feature,
-                Some("sse4a_target_feature") => rust_features.sse4a_target_feature,
-                Some("tbm_target_feature") => rust_features.tbm_target_feature,
-                Some("wasm_target_feature") => rust_features.wasm_target_feature,
-                Some("cmpxchg16b_target_feature") => rust_features.cmpxchg16b_target_feature,
-                Some("adx_target_feature") => rust_features.adx_target_feature,
-                Some("movbe_target_feature") => rust_features.movbe_target_feature,
-                Some("rtm_target_feature") => rust_features.rtm_target_feature,
-                Some("f16c_target_feature") => rust_features.f16c_target_feature,
+            let allowed = match feature_gate.as_ref().map(|s| *s) {
+                Some(sym::arm_target_feature) => rust_features.arm_target_feature,
+                Some(sym::aarch64_target_feature) => rust_features.aarch64_target_feature,
+                Some(sym::hexagon_target_feature) => rust_features.hexagon_target_feature,
+                Some(sym::powerpc_target_feature) => rust_features.powerpc_target_feature,
+                Some(sym::mips_target_feature) => rust_features.mips_target_feature,
+                Some(sym::avx512_target_feature) => rust_features.avx512_target_feature,
+                Some(sym::mmx_target_feature) => rust_features.mmx_target_feature,
+                Some(sym::sse4a_target_feature) => rust_features.sse4a_target_feature,
+                Some(sym::tbm_target_feature) => rust_features.tbm_target_feature,
+                Some(sym::wasm_target_feature) => rust_features.wasm_target_feature,
+                Some(sym::cmpxchg16b_target_feature) => rust_features.cmpxchg16b_target_feature,
+                Some(sym::adx_target_feature) => rust_features.adx_target_feature,
+                Some(sym::movbe_target_feature) => rust_features.movbe_target_feature,
+                Some(sym::rtm_target_feature) => rust_features.rtm_target_feature,
+                Some(sym::f16c_target_feature) => rust_features.f16c_target_feature,
                 Some(name) => bug!("unknown target feature gate {}", name),
                 None => true,
             };
             if !allowed && id.is_local() {
                 feature_gate::emit_feature_err(
                     &tcx.sess.parse_sess,
-                    feature_gate.as_ref().unwrap(),
+                    feature_gate.unwrap(),
                     item.span(),
                     feature_gate::GateIssue::Language,
                     &format!("the target feature `{}` is currently unstable", feature),
@@ -2512,13 +2512,13 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen
 
     let mut inline_span = None;
     for attr in attrs.iter() {
-        if attr.check_name("cold") {
+        if attr.check_name(sym::cold) {
             codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD;
-        } else if attr.check_name("allocator") {
+        } else if attr.check_name(sym::allocator) {
             codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR;
-        } else if attr.check_name("unwind") {
+        } else if attr.check_name(sym::unwind) {
             codegen_fn_attrs.flags |= CodegenFnAttrFlags::UNWIND;
-        } else if attr.check_name("ffi_returns_twice") {
+        } else if attr.check_name(sym::ffi_returns_twice) {
             if tcx.is_foreign_item(id) {
                 codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_RETURNS_TWICE;
             } else {
@@ -2530,21 +2530,21 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen
                     "`#[ffi_returns_twice]` may only be used on foreign functions"
                 ).emit();
             }
-        } else if attr.check_name("rustc_allocator_nounwind") {
+        } else if attr.check_name(sym::rustc_allocator_nounwind) {
             codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_ALLOCATOR_NOUNWIND;
-        } else if attr.check_name("naked") {
+        } else if attr.check_name(sym::naked) {
             codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED;
-        } else if attr.check_name("no_mangle") {
+        } else if attr.check_name(sym::no_mangle) {
             codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE;
-        } else if attr.check_name("rustc_std_internal_symbol") {
+        } else if attr.check_name(sym::rustc_std_internal_symbol) {
             codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL;
-        } else if attr.check_name("no_debug") {
+        } else if attr.check_name(sym::no_debug) {
             codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_DEBUG;
-        } else if attr.check_name("used") {
+        } else if attr.check_name(sym::used) {
             codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED;
-        } else if attr.check_name("thread_local") {
+        } else if attr.check_name(sym::thread_local) {
             codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL;
-        } else if attr.check_name("export_name") {
+        } else if attr.check_name(sym::export_name) {
             if let Some(s) = attr.value_str() {
                 if s.as_str().contains("\0") {
                     // `#[export_name = ...]` will be converted to a null-terminated string,
@@ -2558,7 +2558,7 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen
                 }
                 codegen_fn_attrs.export_name = Some(s);
             }
-        } else if attr.check_name("target_feature") {
+        } else if attr.check_name(sym::target_feature) {
             if tcx.fn_sig(id).unsafety() == Unsafety::Normal {
                 let msg = "#[target_feature(..)] can only be applied to \
                            `unsafe` function";
@@ -2571,11 +2571,11 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen
                 &whitelist,
                 &mut codegen_fn_attrs.target_features,
             );
-        } else if attr.check_name("linkage") {
+        } else if attr.check_name(sym::linkage) {
             if let Some(val) = attr.value_str() {
                 codegen_fn_attrs.linkage = Some(linkage_by_name(tcx, id, &val.as_str()));
             }
-        } else if attr.check_name("link_section") {
+        } else if attr.check_name(sym::link_section) {
             if let Some(val) = attr.value_str() {
                 if val.as_str().bytes().any(|b| b == 0) {
                     let msg = format!(
@@ -2588,7 +2588,7 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen
                     codegen_fn_attrs.link_section = Some(val);
                 }
             }
-        } else if attr.check_name("link_name") {
+        } else if attr.check_name(sym::link_name) {
             codegen_fn_attrs.link_name = attr.value_str();
         }
     }
@@ -2613,9 +2613,9 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen
                         "expected one argument"
                     );
                     InlineAttr::None
-                } else if list_contains_name(&items[..], "always") {
+                } else if list_contains_name(&items[..], sym::always) {
                     InlineAttr::Always
-                } else if list_contains_name(&items[..], "never") {
+                } else if list_contains_name(&items[..], sym::never) {
                     InlineAttr::Never
                 } else {
                     span_err!(
@@ -2649,9 +2649,9 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen
                 if items.len() != 1 {
                     err(attr.span, "expected one argument");
                     OptimizeAttr::None
-                } else if list_contains_name(&items[..], "size") {
+                } else if list_contains_name(&items[..], sym::size) {
                     OptimizeAttr::Size
-                } else if list_contains_name(&items[..], "speed") {
+                } else if list_contains_name(&items[..], sym::speed) {
                     OptimizeAttr::Speed
                 } else {
                     err(items[0].span(), "invalid argument");
diff --git a/src/librustc_typeck/outlives/mod.rs b/src/librustc_typeck/outlives/mod.rs
index e3e2fe7106a..a6b5b99982e 100644
--- a/src/librustc_typeck/outlives/mod.rs
+++ b/src/librustc_typeck/outlives/mod.rs
@@ -5,6 +5,7 @@ use rustc::ty::query::Providers;
 use rustc::ty::subst::UnpackedKind;
 use rustc::ty::{self, CratePredicatesMap, TyCtxt};
 use rustc_data_structures::sync::Lrc;
+use syntax::symbol::sym;
 
 mod explicit;
 mod implicit_infer;
@@ -40,7 +41,7 @@ fn inferred_outlives_of<'a, 'tcx>(
                     .map(|p| *p)
                     .unwrap_or(&[]);
 
-                if tcx.has_attr(item_def_id, "rustc_outlives") {
+                if tcx.has_attr(item_def_id, sym::rustc_outlives) {
                     let mut pred: Vec<String> = predicates
                         .iter()
                         .map(|out_pred| match out_pred {
diff --git a/src/librustc_typeck/outlives/test.rs b/src/librustc_typeck/outlives/test.rs
index e10c8361207..54fd4fad1d1 100644
--- a/src/librustc_typeck/outlives/test.rs
+++ b/src/librustc_typeck/outlives/test.rs
@@ -1,6 +1,7 @@
 use rustc::hir;
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
 use rustc::ty::TyCtxt;
+use syntax::symbol::sym;
 
 pub fn test_inferred_outlives<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     tcx.hir()
@@ -18,7 +19,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for OutlivesTest<'a, 'tcx> {
 
         // For unit testing: check for a special "rustc_outlives"
         // attribute and report an error with various results if found.
-        if self.tcx.has_attr(item_def_id, "rustc_outlives") {
+        if self.tcx.has_attr(item_def_id, sym::rustc_outlives) {
             let inferred_outlives_of = self.tcx.inferred_outlives_of(item_def_id);
             span_err!(
                 self.tcx.sess,
diff --git a/src/librustc_typeck/variance/test.rs b/src/librustc_typeck/variance/test.rs
index d04b1b276a2..b5195826b86 100644
--- a/src/librustc_typeck/variance/test.rs
+++ b/src/librustc_typeck/variance/test.rs
@@ -1,6 +1,7 @@
 use rustc::hir;
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
 use rustc::ty::TyCtxt;
+use syntax::symbol::sym;
 
 pub fn test_variance<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     tcx.hir().krate().visit_all_item_likes(&mut VarianceTest { tcx });
@@ -16,7 +17,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for VarianceTest<'a, 'tcx> {
 
         // For unit testing: check for a special "rustc_variance"
         // attribute and report an error with various results if found.
-        if self.tcx.has_attr(item_def_id, "rustc_variance") {
+        if self.tcx.has_attr(item_def_id, sym::rustc_variance) {
             let variances_of = self.tcx.variances_of(item_def_id);
             span_err!(self.tcx.sess,
                       item.span,
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index d9d6b8e07e9..15108a7dbb9 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -4,6 +4,7 @@ use std::iter::once;
 
 use syntax::ast;
 use syntax::ext::base::{MacroKind, SyntaxExtension};
+use syntax::symbol::sym;
 use syntax_pos::Span;
 
 use rustc::hir;
@@ -186,7 +187,7 @@ pub fn build_external_trait(cx: &DocContext<'_>, did: DefId) -> clean::Trait {
     let generics = (cx.tcx.generics_of(did), &predicates).clean(cx);
     let generics = filter_non_trait_generics(did, generics);
     let (generics, supertrait_bounds) = separate_supertrait_bounds(generics);
-    let is_spotlight = load_attrs(cx, did).has_doc_flag("spotlight");
+    let is_spotlight = load_attrs(cx, did).has_doc_flag(sym::spotlight);
     let is_auto = cx.tcx.trait_is_auto(did);
     clean::Trait {
         auto: auto_trait,
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 3a260db8065..6790b13dbf8 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -32,6 +32,7 @@ use syntax::ext::base::MacroKind;
 use syntax::source_map::{dummy_spanned, Spanned};
 use syntax::ptr::P;
 use syntax::symbol::keywords::{self, Keyword};
+use syntax::symbol::{Symbol, sym};
 use syntax::symbol::InternedString;
 use syntax_pos::{self, Pos, FileName};
 
@@ -170,7 +171,7 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
                     // `compiler_builtins` should be masked too, but we can't apply
                     // `#[doc(masked)]` to the injected `extern crate` because it's unstable.
                     if it.is_extern_crate()
-                        && (it.attrs.has_doc_flag("masked")
+                        && (it.attrs.has_doc_flag(sym::masked)
                             || self.cx.tcx.is_compiler_builtins(it.def_id.krate))
                     {
                         masked_crates.insert(it.def_id.krate);
@@ -261,9 +262,9 @@ impl Clean<ExternalCrate> for CrateNum {
             if let Res::Def(DefKind::Mod, def_id) = res {
                 let attrs = cx.tcx.get_attrs(def_id).clean(cx);
                 let mut prim = None;
-                for attr in attrs.lists("doc") {
+                for attr in attrs.lists(sym::doc) {
                     if let Some(v) = attr.value_str() {
-                        if attr.check_name("primitive") {
+                        if attr.check_name(sym::primitive) {
                             prim = PrimitiveType::from_str(&v.as_str());
                             if prim.is_some() {
                                 break;
@@ -305,9 +306,9 @@ impl Clean<ExternalCrate> for CrateNum {
             if let Res::Def(DefKind::Mod, def_id) = res {
                 let attrs = cx.tcx.get_attrs(def_id).clean(cx);
                 let mut keyword = None;
-                for attr in attrs.lists("doc") {
+                for attr in attrs.lists(sym::doc) {
                     if let Some(v) = attr.value_str() {
-                        if attr.check_name("keyword") {
+                        if attr.check_name(sym::keyword) {
                             keyword = Keyword::from_str(&v.as_str()).ok()
                                                                     .map(|x| x.name().to_string());
                             if keyword.is_some() {
@@ -501,7 +502,7 @@ impl Item {
 
     pub fn is_non_exhaustive(&self) -> bool {
         self.attrs.other_attrs.iter()
-            .any(|a| a.check_name("non_exhaustive"))
+            .any(|a| a.check_name(sym::non_exhaustive))
     }
 
     /// Returns a documentation-level item type from the item.
@@ -669,7 +670,7 @@ impl Clean<Item> for doctree::Module {
 pub struct ListAttributesIter<'a> {
     attrs: slice::Iter<'a, ast::Attribute>,
     current_list: vec::IntoIter<ast::NestedMetaItem>,
-    name: &'a str
+    name: Symbol,
 }
 
 impl<'a> Iterator for ListAttributesIter<'a> {
@@ -702,11 +703,11 @@ impl<'a> Iterator for ListAttributesIter<'a> {
 
 pub trait AttributesExt {
     /// Finds an attribute as List and returns the list of attributes nested inside.
-    fn lists<'a>(&'a self, name: &'a str) -> ListAttributesIter<'a>;
+    fn lists<'a>(&'a self, name: Symbol) -> ListAttributesIter<'a>;
 }
 
 impl AttributesExt for [ast::Attribute] {
-    fn lists<'a>(&'a self, name: &'a str) -> ListAttributesIter<'a> {
+    fn lists<'a>(&'a self, name: Symbol) -> ListAttributesIter<'a> {
         ListAttributesIter {
             attrs: self.iter(),
             current_list: Vec::new().into_iter(),
@@ -717,11 +718,11 @@ impl AttributesExt for [ast::Attribute] {
 
 pub trait NestedAttributesExt {
     /// Returns `true` if the attribute list contains a specific `Word`
-    fn has_word(self, word: &str) -> bool;
+    fn has_word(self, word: Symbol) -> bool;
 }
 
 impl<I: IntoIterator<Item=ast::NestedMetaItem>> NestedAttributesExt for I {
-    fn has_word(self, word: &str) -> bool {
+    fn has_word(self, word: Symbol) -> bool {
         self.into_iter().any(|attr| attr.is_word() && attr.check_name(word))
     }
 }
@@ -803,7 +804,7 @@ impl Attributes {
         if let ast::MetaItemKind::List(ref nmis) = mi.node {
             if nmis.len() == 1 {
                 if let MetaItem(ref cfg_mi) = nmis[0] {
-                    if cfg_mi.check_name("cfg") {
+                    if cfg_mi.check_name(sym::cfg) {
                         if let ast::MetaItemKind::List(ref cfg_nmis) = cfg_mi.node {
                             if cfg_nmis.len() == 1 {
                                 if let MetaItem(ref content_mi) = cfg_nmis[0] {
@@ -827,7 +828,7 @@ impl Attributes {
     {
         mi.meta_item_list().and_then(|list| {
             for meta in list {
-                if meta.check_name("include") {
+                if meta.check_name(sym::include) {
                     // the actual compiled `#[doc(include="filename")]` gets expanded to
                     // `#[doc(include(file="filename", contents="file contents")]` so we need to
                     // look for that instead
@@ -836,11 +837,11 @@ impl Attributes {
                         let mut contents: Option<String> = None;
 
                         for it in list {
-                            if it.check_name("file") {
+                            if it.check_name(sym::file) {
                                 if let Some(name) = it.value_str() {
                                     filename = Some(name.to_string());
                                 }
-                            } else if it.check_name("contents") {
+                            } else if it.check_name(sym::contents) {
                                 if let Some(docs) = it.value_str() {
                                     contents = Some(docs.to_string());
                                 }
@@ -860,9 +861,9 @@ impl Attributes {
         })
     }
 
-    pub fn has_doc_flag(&self, flag: &str) -> bool {
+    pub fn has_doc_flag(&self, flag: Symbol) -> bool {
         for attr in &self.other_attrs {
-            if !attr.check_name("doc") { continue; }
+            if !attr.check_name(sym::doc) { continue; }
 
             if let Some(items) = attr.meta_item_list() {
                 if items.iter().filter_map(|i| i.meta_item()).any(|it| it.check_name(flag)) {
@@ -883,7 +884,7 @@ impl Attributes {
 
         let other_attrs = attrs.iter().filter_map(|attr| {
             attr.with_desugared_doc(|attr| {
-                if attr.check_name("doc") {
+                if attr.check_name(sym::doc) {
                     if let Some(mi) = attr.meta() {
                         if let Some(value) = mi.value_str() {
                             // Extracted #[doc = "..."]
@@ -925,8 +926,8 @@ impl Attributes {
 
         // treat #[target_feature(enable = "feat")] attributes as if they were
         // #[doc(cfg(target_feature = "feat"))] attributes as well
-        for attr in attrs.lists("target_feature") {
-            if attr.check_name("enable") {
+        for attr in attrs.lists(sym::target_feature) {
+            if attr.check_name(sym::enable) {
                 if let Some(feat) = attr.value_str() {
                     let meta = attr::mk_name_value_item_str(Ident::from_str("target_feature"),
                                                             dummy_spanned(feat));
@@ -938,7 +939,7 @@ impl Attributes {
         }
 
         let inner_docs = attrs.iter()
-                              .filter(|a| a.check_name("doc"))
+                              .filter(|a| a.check_name(sym::doc))
                               .next()
                               .map_or(true, |a| a.style == AttrStyle::Inner);
 
@@ -1039,7 +1040,7 @@ impl Hash for Attributes {
 }
 
 impl AttributesExt for Attributes {
-    fn lists<'a>(&'a self, name: &'a str) -> ListAttributesIter<'a> {
+    fn lists<'a>(&'a self, name: Symbol) -> ListAttributesIter<'a> {
         self.other_attrs.lists(name)
     }
 }
@@ -2133,7 +2134,7 @@ pub struct Trait {
 impl Clean<Item> for doctree::Trait {
     fn clean(&self, cx: &DocContext<'_>) -> Item {
         let attrs = self.attrs.clean(cx);
-        let is_spotlight = attrs.has_doc_flag("spotlight");
+        let is_spotlight = attrs.has_doc_flag(sym::spotlight);
         Item {
             name: Some(self.name.clean(cx)),
             attrs: attrs,
@@ -3893,8 +3894,8 @@ impl Clean<Vec<Item>> for doctree::ExternCrate {
     fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> {
 
         let please_inline = self.vis.node.is_pub() && self.attrs.iter().any(|a| {
-            a.check_name("doc") && match a.meta_item_list() {
-                Some(l) => attr::list_contains_name(&l, "inline"),
+            a.check_name(sym::doc) && match a.meta_item_list() {
+                Some(l) => attr::list_contains_name(&l, sym::inline),
                 None => false,
             }
         });
@@ -3935,15 +3936,15 @@ impl Clean<Vec<Item>> for doctree::Import {
         // #[doc(no_inline)] attribute is present.
         // Don't inline doc(hidden) imports so they can be stripped at a later stage.
         let mut denied = !self.vis.node.is_pub() || self.attrs.iter().any(|a| {
-            a.check_name("doc") && match a.meta_item_list() {
-                Some(l) => attr::list_contains_name(&l, "no_inline") ||
-                           attr::list_contains_name(&l, "hidden"),
+            a.check_name(sym::doc) && match a.meta_item_list() {
+                Some(l) => attr::list_contains_name(&l, sym::no_inline) ||
+                           attr::list_contains_name(&l, sym::hidden),
                 None => false,
             }
         });
         // Also check whether imports were asked to be inlined, in case we're trying to re-export a
         // crate in Rust 2018+
-        let please_inline = self.attrs.lists("doc").has_word("inline");
+        let please_inline = self.attrs.lists(sym::doc).has_word(sym::inline);
         let path = self.path.clean(cx);
         let inner = if self.glob {
             if !denied {
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index e91e3a029da..1b099fbd91d 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -18,6 +18,7 @@ use rustc_target::spec::TargetTriple;
 use syntax::source_map;
 use syntax::feature_gate::UnstableFeatures;
 use syntax::json::JsonEmitter;
+use syntax::symbol::sym;
 use errors;
 use errors::emitter::{Emitter, EmitterWriter};
 use parking_lot::ReentrantMutex;
@@ -415,7 +416,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
 
             // Process all of the crate attributes, extracting plugin metadata along
             // with the passes which we are supposed to run.
-            for attr in krate.module.as_ref().unwrap().attrs.lists("doc") {
+            for attr in krate.module.as_ref().unwrap().attrs.lists(sym::doc) {
                 let diag = ctxt.sess().diagnostic();
 
                 let name = attr.name_or_empty();
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 472192a6464..cbaa911eccc 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -50,6 +50,7 @@ use syntax::ast;
 use syntax::ext::base::MacroKind;
 use syntax::source_map::FileName;
 use syntax::feature_gate::UnstableFeatures;
+use syntax::symbol::sym;
 use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId};
 use rustc::middle::privacy::AccessLevels;
 use rustc::middle::stability;
@@ -571,7 +572,7 @@ pub fn run(mut krate: clean::Crate,
     // Crawl the crate attributes looking for attributes which control how we're
     // going to emit HTML
     if let Some(attrs) = krate.module.as_ref().map(|m| &m.attrs) {
-        for attr in attrs.lists("doc") {
+        for attr in attrs.lists(sym::doc) {
             match (attr.name_or_empty().get(), attr.value_str()) {
                 ("html_favicon_url", Some(s)) => {
                     scx.layout.favicon = s.to_string();
@@ -1388,8 +1389,8 @@ fn extern_location(e: &clean::ExternalCrate, extern_url: Option<&str>, dst: &Pat
 
     // Failing that, see if there's an attribute specifying where to find this
     // external crate
-    e.attrs.lists("doc")
-     .filter(|a| a.check_name("html_root_url"))
+    e.attrs.lists(sym::doc)
+     .filter(|a| a.check_name(sym::html_root_url))
      .filter_map(|a| a.value_str())
      .map(|url| {
         let mut url = url.to_string();
@@ -1779,8 +1780,8 @@ impl<'a> Cache {
             let path = self.paths.get(&item.def_id)
                                  .map(|p| p.0[..p.0.len() - 1].join("::"))
                                  .unwrap_or("std".to_owned());
-            for alias in item.attrs.lists("doc")
-                                   .filter(|a| a.check_name("alias"))
+            for alias in item.attrs.lists(sym::doc)
+                                   .filter(|a| a.check_name(sym::alias))
                                    .filter_map(|a| a.value_str()
                                                     .map(|s| s.to_string().replace("\"", "")))
                                    .filter(|v| !v.is_empty())
diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs
index fe407fa24d9..4ee09f7096b 100644
--- a/src/librustdoc/passes/calculate_doc_coverage.rs
+++ b/src/librustdoc/passes/calculate_doc_coverage.rs
@@ -5,6 +5,7 @@ use crate::passes::Pass;
 
 use syntax::attr;
 use syntax_pos::FileName;
+use syntax::symbol::sym;
 
 use std::collections::BTreeMap;
 use std::ops;
@@ -131,7 +132,7 @@ impl fold::DocFolder for CoverageCalculator {
                 return Some(i);
             }
             clean::ImplItem(ref impl_)
-                if attr::contains_name(&i.attrs.other_attrs, "automatically_derived")
+                if attr::contains_name(&i.attrs.other_attrs, sym::automatically_derived)
                     || impl_.synthetic || impl_.blanket_impl.is_some() =>
             {
                 // built-in derives get the `#[automatically_derived]` attribute, and
diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs
index 8d33cd72e29..70cd4b72199 100644
--- a/src/librustdoc/passes/collect_trait_impls.rs
+++ b/src/librustdoc/passes/collect_trait_impls.rs
@@ -5,6 +5,7 @@ use super::Pass;
 
 use rustc::util::nodemap::FxHashSet;
 use rustc::hir::def_id::DefId;
+use syntax::symbol::sym;
 
 pub const COLLECT_TRAIT_IMPLS: Pass = Pass {
     name: "collect-trait-impls",
@@ -68,7 +69,7 @@ pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate {
             inline::build_impl(cx, def_id, &mut new_items);
 
             // FIXME(eddyb) is this `doc(hidden)` check needed?
-            if !cx.tcx.get_attrs(def_id).lists("doc").has_word("hidden") {
+            if !cx.tcx.get_attrs(def_id).lists(sym::doc).has_word(sym::hidden) {
                 let self_ty = cx.tcx.type_of(def_id);
                 let impls = get_auto_trait_and_blanket_impls(cx, self_ty, def_id);
                 let mut renderinfo = cx.renderinfo.borrow_mut();
@@ -154,7 +155,7 @@ impl<'a, 'tcx> DocFolder for SyntheticImplCollector<'a, 'tcx> {
     fn fold_item(&mut self, i: Item) -> Option<Item> {
         if i.is_struct() || i.is_enum() || i.is_union() {
             // FIXME(eddyb) is this `doc(hidden)` check needed?
-            if !self.cx.tcx.get_attrs(i.def_id).lists("doc").has_word("hidden") {
+            if !self.cx.tcx.get_attrs(i.def_id).lists(sym::doc).has_word(sym::hidden) {
                 self.impls.extend(get_auto_trait_and_blanket_impls(
                     self.cx,
                     self.cx.tcx.type_of(i.def_id),
diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs
index 240299c212a..da8977544f6 100644
--- a/src/librustdoc/passes/strip_hidden.rs
+++ b/src/librustdoc/passes/strip_hidden.rs
@@ -1,5 +1,6 @@
 use rustc::util::nodemap::DefIdSet;
 use std::mem;
+use syntax::symbol::sym;
 
 use crate::clean::{self, AttributesExt, NestedAttributesExt};
 use crate::clean::Item;
@@ -37,7 +38,7 @@ struct Stripper<'a> {
 
 impl<'a> DocFolder for Stripper<'a> {
     fn fold_item(&mut self, i: Item) -> Option<Item> {
-        if i.attrs.lists("doc").has_word("hidden") {
+        if i.attrs.lists(sym::doc).has_word(sym::hidden) {
             debug!("strip_hidden: stripping {} {:?}", i.type_(), i.name);
             // use a dedicated hidden item for given item type if any
             match i.inner {
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 5c0a4da1cd7..e40dbe52ffe 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -11,10 +11,6 @@ use syntax::ast;
 use syntax::source_map::SourceMap;
 use syntax::edition::Edition;
 use syntax::feature_gate::UnstableFeatures;
-use syntax_pos::{BytePos, DUMMY_SP, Pos, Span, FileName};
-use tempfile::Builder as TempFileBuilder;
-use testing;
-
 use std::env;
 use std::io::prelude::*;
 use std::io;
@@ -23,6 +19,10 @@ use std::path::PathBuf;
 use std::process::Command;
 use std::str;
 use std::sync::{Arc, Mutex};
+use syntax::symbol::sym;
+use syntax_pos::{BytePos, DUMMY_SP, Pos, Span, FileName};
+use tempfile::Builder as TempFileBuilder;
+use testing;
 
 use crate::clean::Attributes;
 use crate::config::Options;
@@ -137,17 +137,17 @@ fn scrape_test_config(krate: &::rustc::hir::Crate) -> TestOptions {
     };
 
     let test_attrs: Vec<_> = krate.attrs.iter()
-        .filter(|a| a.check_name("doc"))
+        .filter(|a| a.check_name(sym::doc))
         .flat_map(|a| a.meta_item_list().unwrap_or_else(Vec::new))
-        .filter(|a| a.check_name("test"))
+        .filter(|a| a.check_name(sym::test))
         .collect();
     let attrs = test_attrs.iter().flat_map(|a| a.meta_item_list().unwrap_or(&[]));
 
     for attr in attrs {
-        if attr.check_name("no_crate_inject") {
+        if attr.check_name(sym::no_crate_inject) {
             opts.no_crate_inject = true;
         }
-        if attr.check_name("attr") {
+        if attr.check_name(sym::attr) {
             if let Some(l) = attr.meta_item_list() {
                 for item in l {
                     opts.attrs.push(pprust::meta_list_item_to_string(item));
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 94d2d7ffdb8..eb9de43e388 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -10,6 +10,7 @@ use syntax::ast;
 use syntax::attr;
 use syntax::ext::base::MacroKind;
 use syntax::source_map::Spanned;
+use syntax::symbol::sym;
 use syntax_pos::{self, Span};
 
 use std::mem;
@@ -165,11 +166,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                     body: hir::BodyId) {
         debug!("Visiting fn");
         let macro_kind = item.attrs.iter().filter_map(|a| {
-            if a.check_name("proc_macro") {
+            if a.check_name(sym::proc_macro) {
                 Some(MacroKind::Bang)
-            } else if a.check_name("proc_macro_derive") {
+            } else if a.check_name(sym::proc_macro_derive) {
                 Some(MacroKind::Derive)
-            } else if a.check_name("proc_macro_attribute") {
+            } else if a.check_name(sym::proc_macro_attribute) {
                 Some(MacroKind::Attr)
             } else {
                 None
@@ -178,7 +179,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         match macro_kind {
             Some(kind) => {
                 let name = if kind == MacroKind::Derive {
-                    item.attrs.lists("proc_macro_derive")
+                    item.attrs.lists(sym::proc_macro_derive)
                               .filter_map(|mi| mi.ident())
                               .next()
                               .expect("proc-macro derives require a name")
@@ -188,8 +189,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                 };
 
                 let mut helpers = Vec::new();
-                for mi in item.attrs.lists("proc_macro_derive") {
-                    if !mi.check_name("attributes") {
+                for mi in item.attrs.lists(sym::proc_macro_derive) {
+                    if !mi.check_name(sym::attributes) {
                         continue;
                     }
 
@@ -274,7 +275,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         fn inherits_doc_hidden(cx: &core::DocContext<'_>, mut node: hir::HirId) -> bool {
             while let Some(id) = cx.tcx.hir().get_enclosing_scope(node) {
                 node = id;
-                if cx.tcx.hir().attrs_by_hir_id(node).lists("doc").has_word("hidden") {
+                if cx.tcx.hir().attrs_by_hir_id(node)
+                    .lists(sym::doc).has_word(sym::hidden) {
                     return true;
                 }
                 if node == hir::CRATE_HIR_ID {
@@ -295,8 +297,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
 
         let use_attrs = tcx.hir().attrs_by_hir_id(id);
         // Don't inline `doc(hidden)` imports so they can be stripped at a later stage.
-        let is_no_inline = use_attrs.lists("doc").has_word("no_inline") ||
-                           use_attrs.lists("doc").has_word("hidden");
+        let is_no_inline = use_attrs.lists(sym::doc).has_word(sym::no_inline) ||
+                           use_attrs.lists(sym::doc).has_word(sym::hidden);
 
         // For cross-crate impl inlining we need to know whether items are
         // reachable in documentation -- a previously nonreachable item can be
@@ -304,7 +306,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         // (this is done here because we need to know this upfront).
         if !res_did.is_local() && !is_no_inline {
             let attrs = clean::inline::load_attrs(self.cx, res_did);
-            let self_is_hidden = attrs.lists("doc").has_word("hidden");
+            let self_is_hidden = attrs.lists(sym::doc).has_word(sym::hidden);
             match res {
                 Res::Def(DefKind::Trait, did) |
                 Res::Def(DefKind::Struct, did) |
@@ -432,8 +434,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                 if item.vis.node.is_pub() && self.inside_public_path {
                     let please_inline = item.attrs.iter().any(|item| {
                         match item.meta_item_list() {
-                            Some(ref list) if item.check_name("doc") => {
-                                list.iter().any(|i| i.check_name("inline"))
+                            Some(ref list) if item.check_name(sym::doc) => {
+                                list.iter().any(|i| i.check_name(sym::inline))
                             }
                             _ => false,
                         }
diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs
index 326c9a10f7d..2547e3a06e9 100644
--- a/src/librustdoc/visit_lib.rs
+++ b/src/librustdoc/visit_lib.rs
@@ -3,6 +3,7 @@ use rustc::hir::def::{Res, DefKind};
 use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId};
 use rustc::ty::Visibility;
 use rustc::util::nodemap::FxHashSet;
+use syntax::symbol::sym;
 
 use std::cell::RefMut;
 
@@ -42,7 +43,7 @@ impl<'a, 'tcx> LibEmbargoVisitor<'a, 'tcx> {
 
     // Updates node level and returns the updated level
     fn update(&mut self, did: DefId, level: Option<AccessLevel>) -> Option<AccessLevel> {
-        let is_hidden = self.cx.tcx.get_attrs(did).lists("doc").has_word("hidden");
+        let is_hidden = self.cx.tcx.get_attrs(did).lists(sym::doc).has_word(sym::hidden);
 
         let old_level = self.access_levels.map.get(&did).cloned();
         // Accessibility levels can only grow
diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs
index db821f4e536..a8310c48b96 100644
--- a/src/libsyntax/attr/builtin.rs
+++ b/src/libsyntax/attr/builtin.rs
@@ -5,7 +5,7 @@ use crate::feature_gate::{Features, GatedCfg};
 use crate::parse::ParseSess;
 
 use errors::{Applicability, Handler};
-use syntax_pos::{symbol::Symbol, Span};
+use syntax_pos::{symbol::Symbol, symbol::sym, Span};
 
 use super::{mark_used, MetaItemKind};
 
@@ -80,13 +80,13 @@ pub enum UnwindAttr {
 /// Determine what `#[unwind]` attribute is present in `attrs`, if any.
 pub fn find_unwind_attr(diagnostic: Option<&Handler>, attrs: &[Attribute]) -> Option<UnwindAttr> {
     attrs.iter().fold(None, |ia, attr| {
-        if attr.check_name("unwind") {
+        if attr.check_name(sym::unwind) {
             if let Some(meta) = attr.meta() {
                 if let MetaItemKind::List(items) = meta.node {
                     if items.len() == 1 {
-                        if items[0].check_name("allowed") {
+                        if items[0].check_name(sym::allowed) {
                             return Some(UnwindAttr::Allowed);
-                        } else if items[0].check_name("aborts") {
+                        } else if items[0].check_name(sym::aborts) {
                             return Some(UnwindAttr::Aborts);
                         }
                     }
@@ -153,9 +153,9 @@ pub struct RustcDeprecation {
 
 /// Checks if `attrs` contains an attribute like `#![feature(feature_name)]`.
 /// This will not perform any "sanity checks" on the form of the attributes.
-pub fn contains_feature_attr(attrs: &[Attribute], feature_name: &str) -> bool {
+pub fn contains_feature_attr(attrs: &[Attribute], feature_name: Symbol) -> bool {
     attrs.iter().any(|item| {
-        item.check_name("feature") &&
+        item.check_name(sym::feature) &&
         item.meta_item_list().map(|list| {
             list.iter().any(|mi| mi.is_word() && mi.check_name(feature_name))
         }).unwrap_or(false)
@@ -482,7 +482,7 @@ fn find_stability_generic<'a, I>(sess: &ParseSess,
 }
 
 pub fn find_crate_name(attrs: &[Attribute]) -> Option<Symbol> {
-    super::first_attr_value_str_by_name(attrs, "crate_name")
+    super::first_attr_value_str_by_name(attrs, sym::crate_name)
 }
 
 /// Tests if a cfg-pattern matches the cfg set
@@ -593,7 +593,7 @@ fn find_deprecation_generic<'a, I>(sess: &ParseSess,
     let diagnostic = &sess.span_diagnostic;
 
     'outer: for attr in attrs_iter {
-        if !attr.check_name("deprecated") {
+        if !attr.check_name(sym::deprecated) {
             continue;
         }
 
@@ -790,7 +790,7 @@ pub fn find_repr_attrs(sess: &ParseSess, attr: &Attribute) -> Vec<ReprAttr> {
                     }
                 } else {
                     if let Some(meta_item) = item.meta_item() {
-                        if meta_item.check_name("align") {
+                        if meta_item.check_name(sym::align) {
                             if let MetaItemKind::NameValue(ref value) = meta_item.node {
                                 recognised = true;
                                 let mut err = struct_span_err!(diagnostic, item.span(), E0693,
diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs
index 07e4bbf78ff..c0defa1c6e0 100644
--- a/src/libsyntax/attr/mod.rs
+++ b/src/libsyntax/attr/mod.rs
@@ -81,10 +81,7 @@ impl NestedMetaItem {
     }
 
     /// Returns `true` if this list item is a MetaItem with a name of `name`.
-    pub fn check_name<T>(&self, name: T) -> bool
-    where
-        Path: PartialEq<T>,
-    {
+    pub fn check_name(&self, name: Symbol) -> bool {
         self.meta_item().map_or(false, |meta_item| meta_item.check_name(name))
     }
 
@@ -154,10 +151,7 @@ impl Attribute {
     /// attribute is marked as used.
     ///
     /// To check the attribute name without marking it used, use the `path` field directly.
-    pub fn check_name<T>(&self, name: T) -> bool
-    where
-        Path: PartialEq<T>,
-    {
+    pub fn check_name(&self, name: Symbol) -> bool {
         let matches = self.path == name;
         if matches {
             mark_used(self);
@@ -250,10 +244,7 @@ impl MetaItem {
         }
     }
 
-    pub fn check_name<T>(&self, name: T) -> bool
-    where
-        Path: PartialEq<T>,
-    {
+    pub fn check_name(&self, name: Symbol) -> bool {
         self.path == name
     }
 
@@ -430,28 +421,28 @@ pub fn mk_sugared_doc_attr(id: AttrId, text: Symbol, span: Span) -> Attribute {
     }
 }
 
-pub fn list_contains_name(items: &[NestedMetaItem], name: &str) -> bool {
+pub fn list_contains_name(items: &[NestedMetaItem], name: Symbol) -> bool {
     items.iter().any(|item| {
         item.check_name(name)
     })
 }
 
-pub fn contains_name(attrs: &[Attribute], name: &str) -> bool {
+pub fn contains_name(attrs: &[Attribute], name: Symbol) -> bool {
     attrs.iter().any(|item| {
         item.check_name(name)
     })
 }
 
-pub fn find_by_name<'a>(attrs: &'a [Attribute], name: &str) -> Option<&'a Attribute> {
+pub fn find_by_name<'a>(attrs: &'a [Attribute], name: Symbol) -> Option<&'a Attribute> {
     attrs.iter().find(|attr| attr.check_name(name))
 }
 
-pub fn filter_by_name<'a>(attrs: &'a [Attribute], name: &'a str)
+pub fn filter_by_name<'a>(attrs: &'a [Attribute], name: Symbol)
     -> impl Iterator<Item = &'a Attribute> {
     attrs.iter().filter(move |attr| attr.check_name(name))
 }
 
-pub fn first_attr_value_str_by_name(attrs: &[Attribute], name: &str) -> Option<Symbol> {
+pub fn first_attr_value_str_by_name(attrs: &[Attribute], name: Symbol) -> Option<Symbol> {
     attrs.iter()
         .find(|at| at.check_name(name))
         .and_then(|at| at.value_str())
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs
index 18173628a26..c82936afa3d 100644
--- a/src/libsyntax/config.rs
+++ b/src/libsyntax/config.rs
@@ -12,6 +12,7 @@ use crate::edition::Edition;
 use crate::mut_visit::*;
 use crate::parse::{token, ParseSess};
 use crate::ptr::P;
+use crate::symbol::sym;
 use crate::util::map_in_place::MapInPlace;
 
 use errors::Applicability;
@@ -90,7 +91,7 @@ impl<'a> StripUnconfigured<'a> {
     /// is in the original source file. Gives a compiler error if the syntax of
     /// the attribute is incorrect.
     fn process_cfg_attr(&mut self, attr: ast::Attribute) -> Vec<ast::Attribute> {
-        if !attr.check_name("cfg_attr") {
+        if !attr.check_name(sym::cfg_attr) {
             return vec![attr];
         }
 
@@ -205,7 +206,7 @@ impl<'a> StripUnconfigured<'a> {
     pub fn maybe_emit_expr_attr_err(&self, attr: &ast::Attribute) {
         if !self.features.map(|features| features.stmt_expr_attributes).unwrap_or(true) {
             let mut err = feature_err(self.sess,
-                                      "stmt_expr_attributes",
+                                      sym::stmt_expr_attributes,
                                       attr.span,
                                       GateIssue::Language,
                                       EXPLAIN_STMT_ATTR_SYNTAX);
@@ -285,9 +286,9 @@ impl<'a> StripUnconfigured<'a> {
     /// See issue #51279.
     pub fn disallow_cfg_on_generic_param(&mut self, param: &ast::GenericParam) {
         for attr in param.attrs() {
-            let offending_attr = if attr.check_name("cfg") {
+            let offending_attr = if attr.check_name(sym::cfg) {
                 "cfg"
-            } else if attr.check_name("cfg_attr") {
+            } else if attr.check_name(sym::cfg_attr) {
                 "cfg_attr"
             } else {
                 continue;
@@ -350,5 +351,5 @@ impl<'a> MutVisitor for StripUnconfigured<'a> {
 }
 
 fn is_cfg(attr: &ast::Attribute) -> bool {
-    attr.check_name("cfg")
+    attr.check_name(sym::cfg)
 }
diff --git a/src/libsyntax/entry.rs b/src/libsyntax/entry.rs
index 09e26e29d86..267f863ce35 100644
--- a/src/libsyntax/entry.rs
+++ b/src/libsyntax/entry.rs
@@ -1,5 +1,6 @@
 use crate::attr;
 use crate::ast::{Item, ItemKind};
+use crate::symbol::sym;
 
 pub enum EntryPointType {
     None,
@@ -14,9 +15,9 @@ pub enum EntryPointType {
 pub fn entry_point_type(item: &Item, depth: usize) -> EntryPointType {
     match item.node {
         ItemKind::Fn(..) => {
-            if attr::contains_name(&item.attrs, "start") {
+            if attr::contains_name(&item.attrs, sym::start) {
                 EntryPointType::Start
-            } else if attr::contains_name(&item.attrs, "main") {
+            } else if attr::contains_name(&item.attrs, sym::main) {
                 EntryPointType::MainAttr
             } else if item.ident.name == "main" {
                 if depth == 1 {
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 82358679c0e..7ebfcfd176a 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -14,7 +14,7 @@ use crate::parse::token::{self, Token};
 use crate::parse::parser::Parser;
 use crate::ptr::P;
 use crate::symbol::Symbol;
-use crate::symbol::keywords;
+use crate::symbol::{keywords, sym};
 use crate::tokenstream::{TokenStream, TokenTree};
 use crate::visit::{self, Visitor};
 use crate::util::map_in_place::MapInPlace;
@@ -356,7 +356,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                     self.collect_invocations(fragment, &[])
                 } else if let InvocationKind::Attr { attr: None, traits, item, .. } = invoc.kind {
                     if !item.derive_allowed() {
-                        let attr = attr::find_by_name(item.attrs(), "derive")
+                        let attr = attr::find_by_name(item.attrs(), sym::derive)
                             .expect("`derive` attribute should exist");
                         let span = attr.span;
                         let mut err = self.cx.mut_span_err(span,
@@ -510,7 +510,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
         if invoc.fragment_kind == AstFragmentKind::ForeignItems &&
            !self.cx.ecfg.macros_in_extern_enabled() {
             if let SyntaxExtension::NonMacroAttr { .. } = *ext {} else {
-                emit_feature_err(&self.cx.parse_sess, "macros_in_extern",
+                emit_feature_err(&self.cx.parse_sess, sym::macros_in_extern,
                                  invoc.span(), GateIssue::Language,
                                  "macro invocations in `extern {}` blocks are experimental");
             }
@@ -636,7 +636,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
             Annotatable::Item(ref item) => {
                 match item.node {
                     ItemKind::Mod(_) if self.cx.ecfg.proc_macro_hygiene() => return,
-                    ItemKind::Mod(_) => ("modules", "proc_macro_hygiene"),
+                    ItemKind::Mod(_) => ("modules", sym::proc_macro_hygiene),
                     _ => return,
                 }
             }
@@ -645,8 +645,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
             Annotatable::ForeignItem(_) => return,
             Annotatable::Stmt(_) |
             Annotatable::Expr(_) if self.cx.ecfg.proc_macro_hygiene() => return,
-            Annotatable::Stmt(_) => ("statements", "proc_macro_hygiene"),
-            Annotatable::Expr(_) => ("expressions", "proc_macro_hygiene"),
+            Annotatable::Stmt(_) => ("statements", sym::proc_macro_hygiene),
+            Annotatable::Expr(_) => ("expressions", sym::proc_macro_hygiene),
         };
         emit_feature_err(
             self.cx.parse_sess,
@@ -681,7 +681,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                 if let ast::ItemKind::MacroDef(_) = i.node {
                     emit_feature_err(
                         self.parse_sess,
-                        "proc_macro_hygiene",
+                        sym::proc_macro_hygiene,
                         self.span,
                         GateIssue::Language,
                         "procedural macros cannot expand to macro definitions",
@@ -724,13 +724,13 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                 // don't stability-check macros in the same crate
                 // (the only time this is null is for syntax extensions registered as macros)
                 if def_site_span.map_or(false, |def_span| !crate_span.contains(def_span))
-                    && !span.allows_unstable(&feature.as_str())
+                    && !span.allows_unstable(feature)
                     && this.cx.ecfg.features.map_or(true, |feats| {
                     // macro features will count as lib features
                     !feats.declared_lib_features.iter().any(|&(feat, _)| feat == feature)
                 }) {
                     let explain = format!("macro {}! is unstable", path);
-                    emit_feature_err(this.cx.parse_sess, &*feature.as_str(), span,
+                    emit_feature_err(this.cx.parse_sess, feature, span,
                                      GateIssue::Library(Some(issue)), &explain);
                     this.cx.trace_macros_diag();
                 }
@@ -885,7 +885,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
         }
         emit_feature_err(
             self.cx.parse_sess,
-            "proc_macro_hygiene",
+            sym::proc_macro_hygiene,
             span,
             GateIssue::Language,
             &format!("procedural macros cannot be expanded to {}", kind),
@@ -1118,7 +1118,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
         if let Some(attr) = &attr {
             if !self.cx.ecfg.enable_custom_inner_attributes() &&
                attr.style == ast::AttrStyle::Inner && attr.path != "test" {
-                emit_feature_err(&self.cx.parse_sess, "custom_inner_attributes",
+                emit_feature_err(&self.cx.parse_sess, sym::custom_inner_attributes,
                                  attr.span, GateIssue::Language,
                                  "non-builtin inner attributes are unstable");
             }
@@ -1352,7 +1352,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
                 let inline_module = item.span.contains(inner) || inner.is_dummy();
 
                 if inline_module {
-                    if let Some(path) = attr::first_attr_value_str_by_name(&item.attrs, "path") {
+                    if let Some(path) = attr::first_attr_value_str_by_name(&item.attrs, sym::path) {
                         self.cx.current_expansion.directory_ownership =
                             DirectoryOwnership::Owned { relative: None };
                         module.directory.push(&*path.as_str());
@@ -1485,19 +1485,19 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
     fn visit_attribute(&mut self, at: &mut ast::Attribute) {
         // turn `#[doc(include="filename")]` attributes into `#[doc(include(file="filename",
         // contents="file contents")]` attributes
-        if !at.check_name("doc") {
+        if !at.check_name(sym::doc) {
             return noop_visit_attribute(at, self);
         }
 
         if let Some(list) = at.meta_item_list() {
-            if !list.iter().any(|it| it.check_name("include")) {
+            if !list.iter().any(|it| it.check_name(sym::include)) {
                 return noop_visit_attribute(at, self);
             }
 
             let mut items = vec![];
 
             for mut it in list {
-                if !it.check_name("include") {
+                if !it.check_name(sym::include) {
                     items.push({ noop_visit_meta_list_item(&mut it, self); it });
                     continue;
                 }
diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs
index 549de1628eb..e1cb90d9e71 100644
--- a/src/libsyntax/ext/source_util.rs
+++ b/src/libsyntax/ext/source_util.rs
@@ -4,7 +4,7 @@ use crate::ext::build::AstBuilder;
 use crate::parse::{self, token, DirectoryOwnership};
 use crate::print::pprust;
 use crate::ptr::P;
-use crate::symbol::Symbol;
+use crate::symbol::{Symbol, sym};
 use crate::tokenstream;
 
 use smallvec::SmallVec;
@@ -44,7 +44,7 @@ pub fn expand_column(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTr
 /* __rust_unstable_column!(): expands to the current column number */
 pub fn expand_column_gated(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
                   -> Box<dyn base::MacResult+'static> {
-    if sp.allows_unstable("__rust_unstable_column") {
+    if sp.allows_unstable(sym::__rust_unstable_column) {
         expand_column(cx, sp, tts)
     } else {
         cx.span_fatal(sp, "the __rust_unstable_column macro is unstable");
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index a53cc2fe661..55596210093 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -13,7 +13,7 @@ use crate::parse::{Directory, ParseSess};
 use crate::parse::parser::Parser;
 use crate::parse::token::{self, NtTT};
 use crate::parse::token::Token::*;
-use crate::symbol::Symbol;
+use crate::symbol::{Symbol, sym};
 use crate::tokenstream::{DelimSpan, TokenStream, TokenTree};
 
 use errors::FatalError;
@@ -376,7 +376,7 @@ pub fn compile(
     });
 
     if body.legacy {
-        let allow_internal_unstable = attr::find_by_name(&def.attrs, "allow_internal_unstable")
+        let allow_internal_unstable = attr::find_by_name(&def.attrs, sym::allow_internal_unstable)
             .map(|attr| attr
                 .meta_item_list()
                 .map(|list| list.iter()
@@ -399,11 +399,11 @@ pub fn compile(
                     vec![Symbol::intern("allow_internal_unstable_backcompat_hack")].into()
                 })
             );
-        let allow_internal_unsafe = attr::contains_name(&def.attrs, "allow_internal_unsafe");
+        let allow_internal_unsafe = attr::contains_name(&def.attrs, sym::allow_internal_unsafe);
         let mut local_inner_macros = false;
-        if let Some(macro_export) = attr::find_by_name(&def.attrs, "macro_export") {
+        if let Some(macro_export) = attr::find_by_name(&def.attrs, sym::macro_export) {
             if let Some(l) = macro_export.meta_item_list() {
-                local_inner_macros = attr::list_contains_name(&l, "local_inner_macros");
+                local_inner_macros = attr::list_contains_name(&l, sym::local_inner_macros);
             }
         }
 
@@ -426,7 +426,7 @@ pub fn compile(
             edition,
         }
     } else {
-        let is_transparent = attr::contains_name(&def.attrs, "rustc_transparent_macro");
+        let is_transparent = attr::contains_name(&def.attrs, sym::rustc_transparent_macro);
 
         SyntaxExtension::DeclMacro {
             expander,
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index c4977f92402..53ecb0762ab 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -48,8 +48,8 @@ macro_rules! declare_features {
         /// Represents active features that are currently being implemented or
         /// currently being considered for addition/removal.
         const ACTIVE_FEATURES:
-            &[(&str, &str, Option<u32>, Option<Edition>, fn(&mut Features, Span))] =
-            &[$((stringify!($feature), $ver, $issue, $edition, set!($feature))),+];
+            &[(Symbol, &str, Option<u32>, Option<Edition>, fn(&mut Features, Span))] =
+            &[$((sym::$feature, $ver, $issue, $edition, set!($feature))),+];
 
         /// A set of features to be used by later passes.
         #[derive(Clone)]
@@ -80,22 +80,22 @@ macro_rules! declare_features {
 
     ($((removed, $feature: ident, $ver: expr, $issue: expr, None, $reason: expr),)+) => {
         /// Represents unstable features which have since been removed (it was once Active)
-        const REMOVED_FEATURES: &[(&str, &str, Option<u32>, Option<&str>)] = &[
-            $((stringify!($feature), $ver, $issue, $reason)),+
+        const REMOVED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[
+            $((sym::$feature, $ver, $issue, $reason)),+
         ];
     };
 
     ($((stable_removed, $feature: ident, $ver: expr, $issue: expr, None),)+) => {
         /// Represents stable features which have since been removed (it was once Accepted)
-        const STABLE_REMOVED_FEATURES: &[(&str, &str, Option<u32>, Option<&str>)] = &[
-            $((stringify!($feature), $ver, $issue, None)),+
+        const STABLE_REMOVED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[
+            $((sym::$feature, $ver, $issue, None)),+
         ];
     };
 
     ($((accepted, $feature: ident, $ver: expr, $issue: expr, None),)+) => {
         /// Those language feature has since been Accepted (it was once Active)
-        const ACCEPTED_FEATURES: &[(&str, &str, Option<u32>, Option<&str>)] = &[
-            $((stringify!($feature), $ver, $issue, None)),+
+        const ACCEPTED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[
+            $((sym::$feature, $ver, $issue, None)),+
         ];
     }
 }
@@ -860,7 +860,7 @@ pub enum AttributeType {
 pub enum AttributeGate {
     /// Is gated by a given feature gate, reason
     /// and function to check if enabled
-    Gated(Stability, &'static str, &'static str, fn(&Features) -> bool),
+    Gated(Stability, Symbol, &'static str, fn(&Features) -> bool),
 
     /// Ungated attribute, can be used on all release channels
     Ungated,
@@ -1010,7 +1010,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     (sym::no_implicit_prelude, Normal, template!(Word), Ungated),
     (sym::reexport_test_harness_main, Normal, template!(NameValueStr: "name"), Ungated),
     (sym::link_args, Normal, template!(NameValueStr: "args"), Gated(Stability::Unstable,
-                                "link_args",
+                                sym::link_args,
                                 "the `link_args` attribute is experimental and not \
                                 portable across platforms, it is recommended to \
                                 use `#[link(name = \"foo\")] instead",
@@ -1019,46 +1019,46 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
 
     // RFC #1445.
     (sym::structural_match, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            "structural_match",
+                                            sym::structural_match,
                                             "the semantics of constant patterns is \
                                             not yet settled",
                                             cfg_fn!(structural_match))),
 
     // RFC #2008
     (sym::non_exhaustive, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                        "non_exhaustive",
+                                        sym::non_exhaustive,
                                         "non exhaustive is an experimental feature",
                                         cfg_fn!(non_exhaustive))),
 
     // RFC #1268
     (sym::marker, Normal, template!(Word), Gated(Stability::Unstable,
-                            "marker_trait_attr",
+                            sym::marker_trait_attr,
                             "marker traits is an experimental feature",
                             cfg_fn!(marker_trait_attr))),
 
     (sym::plugin, CrateLevel, template!(List: "name|name(args)"), Gated(Stability::Unstable,
-                                "plugin",
+                                sym::plugin,
                                 "compiler plugins are experimental \
                                 and possibly buggy",
                                 cfg_fn!(plugin))),
 
     (sym::no_std, CrateLevel, template!(Word), Ungated),
     (sym::no_core, CrateLevel, template!(Word), Gated(Stability::Unstable,
-                                "no_core",
+                                sym::no_core,
                                 "no_core is experimental",
                                 cfg_fn!(no_core))),
     (sym::lang, Normal, template!(NameValueStr: "name"), Gated(Stability::Unstable,
-                        "lang_items",
+                        sym::lang_items,
                         "language items are subject to change",
                         cfg_fn!(lang_items))),
     (sym::linkage, Whitelisted, template!(NameValueStr: "external|internal|..."),
                                 Gated(Stability::Unstable,
-                                "linkage",
+                                sym::linkage,
                                 "the `linkage` attribute is experimental \
                                     and not portable across platforms",
                                 cfg_fn!(linkage))),
     (sym::thread_local, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                        "thread_local",
+                                        sym::thread_local,
                                         "`#[thread_local]` is an experimental feature, and does \
                                          not currently handle destructors",
                                         cfg_fn!(thread_local))),
@@ -1067,100 +1067,100 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
                         r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#,
                         NameValueStr: "message"),
                                             Gated(Stability::Unstable,
-                                            "on_unimplemented",
+                                            sym::on_unimplemented,
                                             "the `#[rustc_on_unimplemented]` attribute \
                                             is an experimental feature",
                                             cfg_fn!(on_unimplemented))),
     (sym::rustc_const_unstable, Normal, template!(List: r#"feature = "name""#),
                                             Gated(Stability::Unstable,
-                                            "rustc_const_unstable",
+                                            sym::rustc_const_unstable,
                                             "the `#[rustc_const_unstable]` attribute \
                                             is an internal feature",
                                             cfg_fn!(rustc_const_unstable))),
     (sym::global_allocator, Normal, template!(Word), Ungated),
     (sym::default_lib_allocator, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            "allocator_internals",
+                                            sym::allocator_internals,
                                             "the `#[default_lib_allocator]` \
                                             attribute is an experimental feature",
                                             cfg_fn!(allocator_internals))),
     (sym::needs_allocator, Normal, template!(Word), Gated(Stability::Unstable,
-                                    "allocator_internals",
+                                    sym::allocator_internals,
                                     "the `#[needs_allocator]` \
                                     attribute is an experimental \
                                     feature",
                                     cfg_fn!(allocator_internals))),
     (sym::panic_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                        "panic_runtime",
+                                        sym::panic_runtime,
                                         "the `#[panic_runtime]` attribute is \
                                         an experimental feature",
                                         cfg_fn!(panic_runtime))),
     (sym::needs_panic_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            "needs_panic_runtime",
+                                            sym::needs_panic_runtime,
                                             "the `#[needs_panic_runtime]` \
                                                 attribute is an experimental \
                                                 feature",
                                             cfg_fn!(needs_panic_runtime))),
     (sym::rustc_outlives, Normal, template!(Word), Gated(Stability::Unstable,
-                                    "rustc_attrs",
+                                    sym::rustc_attrs,
                                     "the `#[rustc_outlives]` attribute \
                                     is just used for rustc unit tests \
                                     and will never be stable",
                                     cfg_fn!(rustc_attrs))),
     (sym::rustc_variance, Normal, template!(Word), Gated(Stability::Unstable,
-                                    "rustc_attrs",
+                                    sym::rustc_attrs,
                                     "the `#[rustc_variance]` attribute \
                                     is just used for rustc unit tests \
                                     and will never be stable",
                                     cfg_fn!(rustc_attrs))),
     (sym::rustc_layout, Normal, template!(List: "field1, field2, ..."),
     Gated(Stability::Unstable,
-        "rustc_attrs",
+        sym::rustc_attrs,
         "the `#[rustc_layout]` attribute \
             is just used for rustc unit tests \
             and will never be stable",
         cfg_fn!(rustc_attrs))),
     (sym::rustc_layout_scalar_valid_range_start, Whitelisted, template!(List: "value"),
     Gated(Stability::Unstable,
-        "rustc_attrs",
+        sym::rustc_attrs,
         "the `#[rustc_layout_scalar_valid_range_start]` attribute \
             is just used to enable niche optimizations in libcore \
             and will never be stable",
         cfg_fn!(rustc_attrs))),
     (sym::rustc_layout_scalar_valid_range_end, Whitelisted, template!(List: "value"),
     Gated(Stability::Unstable,
-        "rustc_attrs",
+        sym::rustc_attrs,
         "the `#[rustc_layout_scalar_valid_range_end]` attribute \
             is just used to enable niche optimizations in libcore \
             and will never be stable",
         cfg_fn!(rustc_attrs))),
     (sym::rustc_regions, Normal, template!(Word), Gated(Stability::Unstable,
-                                    "rustc_attrs",
+                                    sym::rustc_attrs,
                                     "the `#[rustc_regions]` attribute \
                                     is just used for rustc unit tests \
                                     and will never be stable",
                                     cfg_fn!(rustc_attrs))),
     (sym::rustc_error, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                    "rustc_attrs",
+                                    sym::rustc_attrs,
                                     "the `#[rustc_error]` attribute \
                                         is just used for rustc unit tests \
                                         and will never be stable",
                                     cfg_fn!(rustc_attrs))),
     (sym::rustc_dump_user_substs, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                    "rustc_attrs",
+                                    sym::rustc_attrs,
                                     "this attribute \
                                         is just used for rustc unit tests \
                                         and will never be stable",
                                     cfg_fn!(rustc_attrs))),
     (sym::rustc_if_this_changed, Whitelisted, template!(Word, List: "DepNode"),
                                                 Gated(Stability::Unstable,
-                                                "rustc_attrs",
+                                                sym::rustc_attrs,
                                                 "the `#[rustc_if_this_changed]` attribute \
                                                 is just used for rustc unit tests \
                                                 and will never be stable",
                                                 cfg_fn!(rustc_attrs))),
     (sym::rustc_then_this_would_need, Whitelisted, template!(List: "DepNode"),
                                                     Gated(Stability::Unstable,
-                                                    "rustc_attrs",
+                                                    sym::rustc_attrs,
                                                     "the `#[rustc_if_this_changed]` attribute \
                                                     is just used for rustc unit tests \
                                                     and will never be stable",
@@ -1168,7 +1168,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     (sym::rustc_dirty, Whitelisted, template!(List: r#"cfg = "...", /*opt*/ label = "...",
                                                     /*opt*/ except = "...""#),
                                     Gated(Stability::Unstable,
-                                    "rustc_attrs",
+                                    sym::rustc_attrs,
                                     "the `#[rustc_dirty]` attribute \
                                         is just used for rustc unit tests \
                                         and will never be stable",
@@ -1176,7 +1176,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     (sym::rustc_clean, Whitelisted, template!(List: r#"cfg = "...", /*opt*/ label = "...",
                                                     /*opt*/ except = "...""#),
                                     Gated(Stability::Unstable,
-                                    "rustc_attrs",
+                                    sym::rustc_attrs,
                                     "the `#[rustc_clean]` attribute \
                                         is just used for rustc unit tests \
                                         and will never be stable",
@@ -1187,7 +1187,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         template!(List: r#"cfg = "...", module = "...""#),
         Gated(
             Stability::Unstable,
-            "rustc_attrs",
+            sym::rustc_attrs,
             "this attribute \
             is just used for rustc unit tests \
             and will never be stable",
@@ -1200,7 +1200,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         template!(List: r#"cfg = "...", module = "...""#),
         Gated(
             Stability::Unstable,
-            "rustc_attrs",
+            sym::rustc_attrs,
             "this attribute \
             is just used for rustc unit tests \
             and will never be stable",
@@ -1210,27 +1210,27 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     (sym::rustc_expected_cgu_reuse, Whitelisted, template!(List: r#"cfg = "...", module = "...",
                                                             kind = "...""#),
                                                     Gated(Stability::Unstable,
-                                                    "rustc_attrs",
+                                                    sym::rustc_attrs,
                                                     "this attribute \
                                                     is just used for rustc unit tests \
                                                     and will never be stable",
                                                     cfg_fn!(rustc_attrs))),
     (sym::rustc_synthetic, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                    "rustc_attrs",
+                                                    sym::rustc_attrs,
                                                     "this attribute \
                                                     is just used for rustc unit tests \
                                                     and will never be stable",
                                                     cfg_fn!(rustc_attrs))),
     (sym::rustc_symbol_name, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            "rustc_attrs",
+                                            sym::rustc_attrs,
                                             "internal rustc attributes will never be stable",
                                             cfg_fn!(rustc_attrs))),
     (sym::rustc_def_path, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                        "rustc_attrs",
+                                        sym::rustc_attrs,
                                         "internal rustc attributes will never be stable",
                                         cfg_fn!(rustc_attrs))),
     (sym::rustc_mir, Whitelisted, template!(List: "arg1, arg2, ..."), Gated(Stability::Unstable,
-                                    "rustc_attrs",
+                                    sym::rustc_attrs,
                                     "the `#[rustc_mir]` attribute \
                                     is just used for rustc unit tests \
                                     and will never be stable",
@@ -1241,7 +1241,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         template!(Word),
         Gated(
             Stability::Unstable,
-            "rustc_attrs",
+            sym::rustc_attrs,
             "the `#[rustc_inherit_overflow_checks]` \
             attribute is just used to control \
             overflow checking behavior of several \
@@ -1252,35 +1252,35 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     ),
 
     (sym::rustc_dump_program_clauses, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                    "rustc_attrs",
+                                                    sym::rustc_attrs,
                                                     "the `#[rustc_dump_program_clauses]` \
                                                     attribute is just used for rustc unit \
                                                     tests and will never be stable",
                                                     cfg_fn!(rustc_attrs))),
     (sym::rustc_test_marker, Normal, template!(Word), Gated(Stability::Unstable,
-                                    "rustc_attrs",
+                                    sym::rustc_attrs,
                                     "the `#[rustc_test_marker]` attribute \
                                     is used internally to track tests",
                                     cfg_fn!(rustc_attrs))),
     (sym::rustc_transparent_macro, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                "rustc_attrs",
+                                                sym::rustc_attrs,
                                                 "used internally for testing macro hygiene",
                                                     cfg_fn!(rustc_attrs))),
     (sym::compiler_builtins, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            "compiler_builtins",
+                                            sym::compiler_builtins,
                                             "the `#[compiler_builtins]` attribute is used to \
                                             identify the `compiler_builtins` crate which \
                                             contains compiler-rt intrinsics and will never be \
                                             stable",
                                         cfg_fn!(compiler_builtins))),
     (sym::sanitizer_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            "sanitizer_runtime",
+                                            sym::sanitizer_runtime,
                                             "the `#[sanitizer_runtime]` attribute is used to \
                                             identify crates that contain the runtime of a \
                                             sanitizer and will never be stable",
                                             cfg_fn!(sanitizer_runtime))),
     (sym::profiler_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            "profiler_runtime",
+                                            sym::profiler_runtime,
                                             "the `#[profiler_runtime]` attribute is used to \
                                             identify the `profiler_builtins` crate which \
                                             contains the profiler runtime and will never be \
@@ -1289,17 +1289,17 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
 
     (sym::allow_internal_unstable, Normal, template!(Word, List: "feat1, feat2, ..."),
                                             Gated(Stability::Unstable,
-                                            "allow_internal_unstable",
+                                            sym::allow_internal_unstable,
                                             EXPLAIN_ALLOW_INTERNAL_UNSTABLE,
                                             cfg_fn!(allow_internal_unstable))),
 
     (sym::allow_internal_unsafe, Normal, template!(Word), Gated(Stability::Unstable,
-                                            "allow_internal_unsafe",
+                                            sym::allow_internal_unsafe,
                                             EXPLAIN_ALLOW_INTERNAL_UNSAFE,
                                             cfg_fn!(allow_internal_unsafe))),
 
     (sym::fundamental, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                    "fundamental",
+                                    sym::fundamental,
                                     "the `#[fundamental]` attribute \
                                         is an experimental feature",
                                     cfg_fn!(fundamental))),
@@ -1309,7 +1309,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
                                     Ungated),
 
     (sym::rustc_copy_clone_marker, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                "rustc_attrs",
+                                                sym::rustc_attrs,
                                                 "internal implementation detail",
                                                 cfg_fn!(rustc_attrs))),
 
@@ -1325,12 +1325,12 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     // lint pass
     (sym::cold, Whitelisted, template!(Word), Ungated),
     (sym::naked, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                "naked_functions",
+                                sym::naked_functions,
                                 "the `#[naked]` attribute \
                                 is an experimental feature",
                                 cfg_fn!(naked_functions))),
     (sym::ffi_returns_twice, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                "ffi_returns_twice",
+                                sym::ffi_returns_twice,
                                 "the `#[ffi_returns_twice]` attribute \
                                 is an experimental feature",
                                 cfg_fn!(ffi_returns_twice))),
@@ -1344,7 +1344,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     (sym::no_builtins, Whitelisted, template!(Word), Ungated),
     (sym::no_debug, Whitelisted, template!(Word), Gated(
         Stability::Deprecated("https://github.com/rust-lang/rust/issues/29721", None),
-        "no_debug",
+        sym::no_debug,
         "the `#[no_debug]` attribute was an experimental feature that has been \
         deprecated due to lack of demand",
         cfg_fn!(no_debug))),
@@ -1354,7 +1354,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         template!(Word),
         Gated(
             Stability::Unstable,
-            "omit_gdb_pretty_printer_section",
+            sym::omit_gdb_pretty_printer_section,
             "the `#[omit_gdb_pretty_printer_section]` \
                 attribute is just used for the Rust test \
                 suite",
@@ -1366,7 +1366,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     template!(Word),
     Gated(Stability::Deprecated("https://github.com/rust-lang/rust/issues/34761",
                                 Some("replace this attribute with `#[may_dangle]`")),
-        "dropck_parametricity",
+        sym::dropck_parametricity,
         "unsafe_destructor_blind_to_params has been replaced by \
             may_dangle and will be removed in the future",
         cfg_fn!(dropck_parametricity))),
@@ -1374,18 +1374,18 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     Normal,
     template!(Word),
     Gated(Stability::Unstable,
-        "dropck_eyepatch",
+        sym::dropck_eyepatch,
         "may_dangle has unstable semantics and may be removed in the future",
         cfg_fn!(dropck_eyepatch))),
     (sym::unwind, Whitelisted, template!(List: "allowed|aborts"), Gated(Stability::Unstable,
-                                "unwind_attributes",
+                                sym::unwind_attributes,
                                 "#[unwind] is experimental",
                                 cfg_fn!(unwind_attributes))),
     (sym::used, Whitelisted, template!(Word), Ungated),
 
     // used in resolve
     (sym::prelude_import, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                        "prelude_import",
+                                        sym::prelude_import,
                                         "`#[prelude_import]` is for use by rustc only",
                                         cfg_fn!(prelude_import))),
 
@@ -1421,7 +1421,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     ),
 
     (sym::rustc_paren_sugar, Normal, template!(Word), Gated(Stability::Unstable,
-                                        "unboxed_closures",
+                                        sym::unboxed_closures,
                                         "unboxed_closures are still evolving",
                                         cfg_fn!(unboxed_closures))),
 
@@ -1431,24 +1431,24 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     (sym::proc_macro, Normal, template!(Word), Ungated),
 
     (sym::rustc_proc_macro_decls, Normal, template!(Word), Gated(Stability::Unstable,
-                                            "rustc_attrs",
+                                            sym::rustc_attrs,
                                             "used internally by rustc",
                                             cfg_fn!(rustc_attrs))),
 
     (sym::allow_fail, Normal, template!(Word), Gated(Stability::Unstable,
-                                "allow_fail",
+                                sym::allow_fail,
                                 "allow_fail attribute is currently unstable",
                                 cfg_fn!(allow_fail))),
 
     (sym::rustc_std_internal_symbol, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                    "rustc_attrs",
+                                    sym::rustc_attrs,
                                     "this is an internal attribute that will \
                                     never be stable",
                                     cfg_fn!(rustc_attrs))),
 
     // whitelists "identity-like" conversion methods to suggest on type mismatch
     (sym::rustc_conversion_suggestion, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                    "rustc_attrs",
+                                                    sym::rustc_attrs,
                                                     "this is an internal attribute that will \
                                                         never be stable",
                                                     cfg_fn!(rustc_attrs))),
@@ -1457,19 +1457,20 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         sym::rustc_args_required_const,
         Whitelisted,
         template!(List: "N"),
-        Gated(Stability::Unstable, "rustc_attrs", "never will be stable", cfg_fn!(rustc_attrs))
+        Gated(Stability::Unstable, sym::rustc_attrs, "never will be stable",
+           cfg_fn!(rustc_attrs))
     ),
     // RFC 2070
     (sym::panic_handler, Normal, template!(Word), Ungated),
 
     (sym::alloc_error_handler, Normal, template!(Word), Gated(Stability::Unstable,
-                        "alloc_error_handler",
+                        sym::alloc_error_handler,
                         "#[alloc_error_handler] is an unstable feature",
                         cfg_fn!(alloc_error_handler))),
 
     // RFC 2412
     (sym::optimize, Whitelisted, template!(List: "size|speed"), Gated(Stability::Unstable,
-                            "optimize_attribute",
+                            sym::optimize_attribute,
                             "#[optimize] attribute is an unstable feature",
                             cfg_fn!(optimize_attribute))),
 
@@ -1483,7 +1484,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     (sym::recursion_limit, CrateLevel, template!(NameValueStr: "N"), Ungated),
     (sym::type_length_limit, CrateLevel, template!(NameValueStr: "N"), Ungated),
     (sym::test_runner, CrateLevel, template!(List: "path"), Gated(Stability::Unstable,
-                    "custom_test_frameworks",
+                    sym::custom_test_frameworks,
                     EXPLAIN_CUSTOM_TEST_FRAMEWORKS,
                     cfg_fn!(custom_test_frameworks))),
 ];
@@ -1503,11 +1504,11 @@ lazy_static! {
 }
 
 // cfg(...)'s that are feature gated
-const GATED_CFGS: &[(&str, &str, fn(&Features) -> bool)] = &[
+const GATED_CFGS: &[(Symbol, Symbol, fn(&Features) -> bool)] = &[
     // (name in cfg, feature, function to check if the feature is enabled)
-    ("target_thread_local", "cfg_target_thread_local", cfg_fn!(cfg_target_thread_local)),
-    ("target_has_atomic", "cfg_target_has_atomic", cfg_fn!(cfg_target_has_atomic)),
-    ("rustdoc", "doc_cfg", cfg_fn!(doc_cfg)),
+    (sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)),
+    (sym::target_has_atomic, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
+    (sym::rustdoc, sym::doc_cfg, cfg_fn!(doc_cfg)),
 ];
 
 #[derive(Debug)]
@@ -1540,7 +1541,7 @@ impl GatedCfg {
 struct Context<'a> {
     features: &'a Features,
     parse_sess: &'a ParseSess,
-    plugin_attributes: &'a [(String, AttributeType)],
+    plugin_attributes: &'a [(Symbol, AttributeType)],
 }
 
 macro_rules! gate_feature_fn {
@@ -1559,11 +1560,11 @@ macro_rules! gate_feature_fn {
 macro_rules! gate_feature {
     ($cx: expr, $feature: ident, $span: expr, $explain: expr) => {
         gate_feature_fn!($cx, |x:&Features| x.$feature, $span,
-                         stringify!($feature), $explain, GateStrength::Hard)
+                         sym::$feature, $explain, GateStrength::Hard)
     };
     ($cx: expr, $feature: ident, $span: expr, $explain: expr, $level: expr) => {
         gate_feature_fn!($cx, |x:&Features| x.$feature, $span,
-                         stringify!($feature), $explain, $level)
+                         sym::$feature, $explain, $level)
     };
 }
 
@@ -1594,8 +1595,8 @@ impl<'a> Context<'a> {
             debug!("check_attribute: {:?} is builtin, {:?}, {:?}", attr.path, ty, gateage);
             return;
         }
-        for &(ref n, ref ty) in self.plugin_attributes {
-            if attr.path == &**n {
+        for &(n, ty) in self.plugin_attributes {
+            if attr.path == n {
                 // Plugins can't gate attributes, so we don't check for it
                 // unlike the code above; we only use this loop to
                 // short-circuit to avoid the checks below.
@@ -1629,7 +1630,7 @@ pub fn check_attribute(attr: &ast::Attribute, parse_sess: &ParseSess, features:
     );
 }
 
-fn find_lang_feature_issue(feature: &str) -> Option<u32> {
+fn find_lang_feature_issue(feature: Symbol) -> Option<u32> {
     if let Some(info) = ACTIVE_FEATURES.iter().find(|t| t.0 == feature) {
         let issue = info.2;
         // FIXME (#28244): enforce that active features have issue numbers
@@ -1661,7 +1662,7 @@ pub enum GateStrength {
 
 pub fn emit_feature_err(
     sess: &ParseSess,
-    feature: &str,
+    feature: Symbol,
     span: Span,
     issue: GateIssue,
     explain: &str,
@@ -1671,7 +1672,7 @@ pub fn emit_feature_err(
 
 pub fn feature_err<'a>(
     sess: &'a ParseSess,
-    feature: &str,
+    feature: Symbol,
     span: Span,
     issue: GateIssue,
     explain: &str,
@@ -1681,7 +1682,7 @@ pub fn feature_err<'a>(
 
 fn leveled_feature_err<'a>(
     sess: &'a ParseSess,
-    feature: &str,
+    feature: Symbol,
     span: Span,
     issue: GateIssue,
     explain: &str,
@@ -1769,13 +1770,13 @@ struct PostExpansionVisitor<'a> {
 macro_rules! gate_feature_post {
     ($cx: expr, $feature: ident, $span: expr, $explain: expr) => {{
         let (cx, span) = ($cx, $span);
-        if !span.allows_unstable(stringify!($feature)) {
+        if !span.allows_unstable(sym::$feature) {
             gate_feature!(cx.context, $feature, span, $explain)
         }
     }};
     ($cx: expr, $feature: ident, $span: expr, $explain: expr, $level: expr) => {{
         let (cx, span) = ($cx, $span);
-        if !span.allows_unstable(stringify!($feature)) {
+        if !span.allows_unstable(sym::$feature) {
             gate_feature!(cx.context, $feature, span, $explain, $level)
         }
     }}
@@ -1957,17 +1958,17 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
             }
 
             ast::ItemKind::Fn(..) => {
-                if attr::contains_name(&i.attrs[..], "plugin_registrar") {
+                if attr::contains_name(&i.attrs[..], sym::plugin_registrar) {
                     gate_feature_post!(&self, plugin_registrar, i.span,
                                        "compiler plugins are experimental and possibly buggy");
                 }
-                if attr::contains_name(&i.attrs[..], "start") {
+                if attr::contains_name(&i.attrs[..], sym::start) {
                     gate_feature_post!(&self, start, i.span,
                                       "a #[start] function is an experimental \
                                        feature whose signature may change \
                                        over time");
                 }
-                if attr::contains_name(&i.attrs[..], "main") {
+                if attr::contains_name(&i.attrs[..], sym::main) {
                     gate_feature_post!(&self, main, i.span,
                                        "declaration of a nonstandard #[main] \
                                         function may change over time, for now \
@@ -1976,7 +1977,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
             }
 
             ast::ItemKind::Struct(..) => {
-                for attr in attr::filter_by_name(&i.attrs[..], "repr") {
+                for attr in attr::filter_by_name(&i.attrs[..], sym::repr) {
                     for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
                         if item.check_name(sym::simd) {
                             gate_feature_post!(&self, repr_simd, attr.span,
@@ -1987,7 +1988,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
             }
 
             ast::ItemKind::Enum(..) => {
-                for attr in attr::filter_by_name(&i.attrs[..], "repr") {
+                for attr in attr::filter_by_name(&i.attrs[..], sym::repr) {
                     for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
                         if item.check_name(sym::align) {
                             gate_feature_post!(&self, repr_align_enum, attr.span,
@@ -2051,7 +2052,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
         match i.node {
             ast::ForeignItemKind::Fn(..) |
             ast::ForeignItemKind::Static(..) => {
-                let link_name = attr::first_attr_value_str_by_name(&i.attrs, "link_name");
+                let link_name = attr::first_attr_value_str_by_name(&i.attrs, sym::link_name);
                 let links_to_llvm = match link_name {
                     Some(val) => val.as_str().starts_with("llvm."),
                     _ => false
@@ -2311,7 +2312,7 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
         if let Some(f_edition) = f_edition {
             if f_edition <= crate_edition {
                 set(&mut features, DUMMY_SP);
-                edition_enabled_features.insert(Symbol::intern(name), crate_edition);
+                edition_enabled_features.insert(name, crate_edition);
             }
         }
     }
@@ -2355,7 +2356,7 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
                             // FIXME(Manishearth) there is currently no way to set
                             // lib features by edition
                             set(&mut features, DUMMY_SP);
-                            edition_enabled_features.insert(Symbol::intern(name), *edition);
+                            edition_enabled_features.insert(name, *edition);
                         }
                     }
                 }
@@ -2438,7 +2439,7 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
 pub fn check_crate(krate: &ast::Crate,
                    sess: &ParseSess,
                    features: &Features,
-                   plugin_attributes: &[(String, AttributeType)],
+                   plugin_attributes: &[(Symbol, AttributeType)],
                    unstable: UnstableFeatures) {
     maybe_stage_features(&sess.span_diagnostic, krate, unstable);
     let ctx = Context {
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 526143b2875..64f3704e808 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -575,13 +575,15 @@ mod tests {
 
     #[test] fn crlf_doc_comments() {
         with_globals(|| {
+            use crate::symbol::sym;
+
             let sess = ParseSess::new(FilePathMapping::empty());
 
             let name_1 = FileName::Custom("crlf_source_1".to_string());
             let source = "/// doc comment\r\nfn foo() {}".to_string();
             let item = parse_item_from_source_str(name_1, source, &sess)
                 .unwrap().unwrap();
-            let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap();
+            let doc = first_attr_value_str_by_name(&item.attrs, sym::doc).unwrap();
             assert_eq!(doc, "/// doc comment");
 
             let name_2 = FileName::Custom("crlf_source_2".to_string());
@@ -596,7 +598,7 @@ mod tests {
             let name_3 = FileName::Custom("clrf_source_3".to_string());
             let source = "/** doc comment\r\n *  with CRLF */\r\nfn foo() {}".to_string();
             let item = parse_item_from_source_str(name_3, source, &sess).unwrap().unwrap();
-            let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap();
+            let doc = first_attr_value_str_by_name(&item.attrs, sym::doc).unwrap();
             assert_eq!(doc, "/** doc comment\n *  with CRLF */");
         });
     }
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index f95981680b9..d3dd6bb1e01 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -46,7 +46,7 @@ use crate::ptr::P;
 use crate::parse::PResult;
 use crate::ThinVec;
 use crate::tokenstream::{self, DelimSpan, TokenTree, TokenStream, TreeAndJoint};
-use crate::symbol::{keywords, Symbol};
+use crate::symbol::{keywords, sym, Symbol};
 
 use errors::{Applicability, DiagnosticBuilder, DiagnosticId, FatalError};
 use rustc_target::spec::abi::{self, Abi};
@@ -7263,7 +7263,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, "path") {
+        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.ownership = DirectoryOwnership::Owned { relative: None };
         } else {
@@ -7283,7 +7283,7 @@ impl<'a> Parser<'a> {
     }
 
     pub fn submod_path_from_attr(attrs: &[Attribute], dir_path: &Path) -> Option<PathBuf> {
-        if let Some(s) = attr::first_attr_value_str_by_name(attrs, "path") {
+        if let Some(s) = attr::first_attr_value_str_by_name(attrs, sym::path) {
             let s = s.as_str();
 
             // On windows, the base path might have the form
diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs
index b9758bd655c..42ca8b7c23c 100644
--- a/src/libsyntax/std_inject.rs
+++ b/src/libsyntax/std_inject.rs
@@ -2,7 +2,7 @@ use crate::ast;
 use crate::attr;
 use crate::edition::Edition;
 use crate::ext::hygiene::{Mark, SyntaxContext};
-use crate::symbol::{Symbol, keywords};
+use crate::symbol::{Symbol, keywords, sym};
 use crate::source_map::{ExpnInfo, MacroAttribute, dummy_spanned, hygiene, respan};
 use crate::ptr::P;
 use crate::tokenstream::TokenStream;
@@ -46,10 +46,10 @@ pub fn maybe_inject_crates_ref(
     let rust_2018 = edition >= Edition::Edition2018;
 
     // the first name in this list is the crate name of the crate with the prelude
-    let names: &[&str] = if attr::contains_name(&krate.attrs, "no_core") {
+    let names: &[&str] = if attr::contains_name(&krate.attrs, sym::no_core) {
         return krate;
-    } else if attr::contains_name(&krate.attrs, "no_std") {
-        if attr::contains_name(&krate.attrs, "compiler_builtins") {
+    } else if attr::contains_name(&krate.attrs, sym::no_std) {
+        if attr::contains_name(&krate.attrs, sym::compiler_builtins) {
             &["core"]
         } else {
             &["core", "compiler_builtins"]
diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs
index 03d0eff266e..8e5e594ce9a 100644
--- a/src/libsyntax/test.rs
+++ b/src/libsyntax/test.rs
@@ -29,7 +29,7 @@ use crate::parse::{token, ParseSess};
 use crate::print::pprust;
 use crate::ast::{self, Ident};
 use crate::ptr::P;
-use crate::symbol::{self, Symbol, keywords};
+use crate::symbol::{self, Symbol, keywords, sym};
 use crate::ThinVec;
 
 struct Test {
@@ -65,8 +65,7 @@ pub fn modify_for_testing(sess: &ParseSess,
     // unconditional, so that the attribute is still marked as used in
     // non-test builds.
     let reexport_test_harness_main =
-        attr::first_attr_value_str_by_name(&krate.attrs,
-                                           "reexport_test_harness_main");
+        attr::first_attr_value_str_by_name(&krate.attrs, sym::reexport_test_harness_main);
 
     // Do this here so that the test_runner crate attribute gets marked as used
     // even in non-test builds
@@ -185,7 +184,7 @@ impl MutVisitor for EntryPointCleaner {
                         ident,
                         attrs: attrs.into_iter()
                             .filter(|attr| {
-                                !attr.check_name("main") && !attr.check_name("start")
+                                !attr.check_name(sym::main) && !attr.check_name(sym::start)
                             })
                             .chain(iter::once(allow_dead_code))
                             .collect(),
@@ -428,11 +427,11 @@ fn visible_path(cx: &TestCtxt<'_>, path: &[Ident]) -> Vec<Ident>{
 }
 
 fn is_test_case(i: &ast::Item) -> bool {
-    attr::contains_name(&i.attrs, "rustc_test_marker")
+    attr::contains_name(&i.attrs, sym::rustc_test_marker)
 }
 
 fn get_test_runner(sd: &errors::Handler, krate: &ast::Crate) -> Option<ast::Path> {
-    let test_attr = attr::find_by_name(&krate.attrs, "test_runner")?;
+    let test_attr = attr::find_by_name(&krate.attrs, sym::test_runner)?;
     test_attr.meta_item_list().map(|meta_list| {
         if meta_list.len() != 1 {
             sd.span_fatal(test_attr.span,
diff --git a/src/libsyntax_ext/asm.rs b/src/libsyntax_ext/asm.rs
index 8edd0e1ae38..6213736ed5f 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;
+use syntax::symbol::{Symbol, sym};
 use syntax::ast::AsmDialect;
 use syntax_pos::Span;
 use syntax::tokenstream;
@@ -47,7 +47,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
                        -> Box<dyn base::MacResult + 'cx> {
     if !cx.ecfg.enable_asm() {
         feature_gate::emit_feature_err(&cx.parse_sess,
-                                       "asm",
+                                       sym::asm,
                                        sp,
                                        feature_gate::GateIssue::Language,
                                        feature_gate::EXPLAIN_ASM);
diff --git a/src/libsyntax_ext/concat_idents.rs b/src/libsyntax_ext/concat_idents.rs
index 8c9eb4bf2d8..77c53f402cc 100644
--- a/src/libsyntax_ext/concat_idents.rs
+++ b/src/libsyntax_ext/concat_idents.rs
@@ -6,7 +6,7 @@ use syntax::feature_gate;
 use syntax::parse::token;
 use syntax::ptr::P;
 use syntax_pos::Span;
-use syntax_pos::symbol::Symbol;
+use syntax_pos::symbol::{Symbol, sym};
 use syntax::tokenstream::TokenTree;
 
 pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt<'_>,
@@ -15,7 +15,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt<'_>,
                               -> Box<dyn base::MacResult + 'cx> {
     if !cx.ecfg.enable_concat_idents() {
         feature_gate::emit_feature_err(&cx.parse_sess,
-                                       "concat_idents",
+                                       sym::concat_idents,
                                        sp,
                                        feature_gate::GateIssue::Language,
                                        feature_gate::EXPLAIN_CONCAT_IDENTS);
diff --git a/src/libsyntax_ext/deriving/clone.rs b/src/libsyntax_ext/deriving/clone.rs
index b347092e1bc..1b0d572324a 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, keywords};
+use syntax::symbol::{Symbol, keywords, sym};
 use syntax_pos::Span;
 
 pub fn expand_deriving_clone(cx: &mut ExtCtxt<'_>,
@@ -37,7 +37,7 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt<'_>,
             match annitem.node {
                 ItemKind::Struct(_, Generics { ref params, .. }) |
                 ItemKind::Enum(_, Generics { ref params, .. }) => {
-                    if attr::contains_name(&annitem.attrs, "rustc_copy_clone_marker") &&
+                    if attr::contains_name(&annitem.attrs, sym::rustc_copy_clone_marker) &&
                         !params.iter().any(|param| match param.kind {
                             ast::GenericParamKind::Type { .. } => true,
                             _ => false,
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index e5939e396e5..228862c830f 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -191,7 +191,7 @@ use syntax::ext::build::AstBuilder;
 use syntax::source_map::{self, respan};
 use syntax::util::map_in_place::MapInPlace;
 use syntax::ptr::P;
-use syntax::symbol::{Symbol, keywords};
+use syntax::symbol::{Symbol, keywords, sym};
 use syntax::parse::ParseSess;
 use syntax_pos::{DUMMY_SP, Span};
 
@@ -426,7 +426,7 @@ impl<'a> TraitDef<'a> {
                     }
                 };
                 let is_always_copy =
-                    attr::contains_name(&item.attrs, "rustc_copy_clone_marker") &&
+                    attr::contains_name(&item.attrs, sym::rustc_copy_clone_marker) &&
                     has_no_type_params;
                 let use_temporaries = is_packed && is_always_copy;
 
diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs
index 24fbc9b6caf..9e54c0634b6 100644
--- a/src/libsyntax_ext/format.rs
+++ b/src/libsyntax_ext/format.rs
@@ -12,7 +12,7 @@ use syntax::ext::build::AstBuilder;
 use syntax::feature_gate;
 use syntax::parse::token;
 use syntax::ptr::P;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 use syntax::tokenstream;
 use syntax_pos::{MultiSpan, Span, DUMMY_SP};
 
@@ -711,12 +711,12 @@ pub fn expand_format_args_nl<'cx>(
     //if !ecx.ecfg.enable_allow_internal_unstable() {
 
     // For some reason, the only one that actually works for `println` is the first check
-    if !sp.allows_unstable("format_args_nl") // the span is marked as `#[allow_insternal_unsable]`
+    if !sp.allows_unstable(sym::format_args_nl) // the span is marked `#[allow_insternal_unsable]`
         && !ecx.ecfg.enable_allow_internal_unstable()  // NOTE: when is this enabled?
         && !ecx.ecfg.enable_format_args_nl()  // enabled using `#[feature(format_args_nl]`
     {
         feature_gate::emit_feature_err(&ecx.parse_sess,
-                                       "format_args_nl",
+                                       sym::format_args_nl,
                                        sp,
                                        feature_gate::GateIssue::Language,
                                        feature_gate::EXPLAIN_FORMAT_ARGS_NL);
diff --git a/src/libsyntax_ext/global_asm.rs b/src/libsyntax_ext/global_asm.rs
index 2baf530aeda..3f2853e4b0e 100644
--- a/src/libsyntax_ext/global_asm.rs
+++ b/src/libsyntax_ext/global_asm.rs
@@ -16,12 +16,12 @@ use syntax::ext::base::{self, *};
 use syntax::feature_gate;
 use syntax::parse::token;
 use syntax::ptr::P;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 use syntax_pos::Span;
 use syntax::tokenstream;
 use smallvec::smallvec;
 
-pub const MACRO: &str = "global_asm";
+pub const MACRO: Symbol = sym::global_asm;
 
 pub fn expand_global_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
                               sp: Span,
diff --git a/src/libsyntax_ext/log_syntax.rs b/src/libsyntax_ext/log_syntax.rs
index 658ce98d268..1be3990837c 100644
--- a/src/libsyntax_ext/log_syntax.rs
+++ b/src/libsyntax_ext/log_syntax.rs
@@ -2,6 +2,7 @@ use syntax::ext::base;
 use syntax::feature_gate;
 use syntax::print;
 use syntax::tokenstream;
+use syntax::symbol::sym;
 use syntax_pos;
 
 pub fn expand_syntax_ext<'cx>(cx: &'cx mut base::ExtCtxt<'_>,
@@ -10,7 +11,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut base::ExtCtxt<'_>,
                               -> Box<dyn base::MacResult + 'cx> {
     if !cx.ecfg.enable_log_syntax() {
         feature_gate::emit_feature_err(&cx.parse_sess,
-                                       "log_syntax",
+                                       sym::log_syntax,
                                        sp,
                                        feature_gate::GateIssue::Language,
                                        feature_gate::EXPLAIN_LOG_SYNTAX);
diff --git a/src/libsyntax_ext/proc_macro_decls.rs b/src/libsyntax_ext/proc_macro_decls.rs
index f0390ba3d40..5ced1400acb 100644
--- a/src/libsyntax_ext/proc_macro_decls.rs
+++ b/src/libsyntax_ext/proc_macro_decls.rs
@@ -13,12 +13,16 @@ use syntax::mut_visit::MutVisitor;
 use syntax::parse::ParseSess;
 use syntax::ptr::P;
 use syntax::symbol::Symbol;
-use syntax::symbol::keywords;
+use syntax::symbol::{keywords, sym};
 use syntax::visit::{self, Visitor};
 
 use syntax_pos::{Span, DUMMY_SP};
 
-const PROC_MACRO_KINDS: [&str; 3] = ["proc_macro_derive", "proc_macro_attribute", "proc_macro"];
+const PROC_MACRO_KINDS: [Symbol; 3] = [
+    sym::proc_macro_derive,
+    sym::proc_macro_attribute,
+    sym::proc_macro
+];
 
 struct ProcMacroDerive {
     trait_name: ast::Name,
@@ -139,7 +143,7 @@ impl<'a> CollectProcMacros<'a> {
 
         let attributes_attr = list.get(1);
         let proc_attrs: Vec<_> = if let Some(attr) = attributes_attr {
-            if !attr.check_name("attributes") {
+            if !attr.check_name(sym::attributes) {
                 self.handler.span_err(attr.span(), "second argument must be `attributes`")
             }
             attr.meta_item_list().unwrap_or_else(|| {
@@ -231,7 +235,7 @@ impl<'a> CollectProcMacros<'a> {
 impl<'a> Visitor<'a> for CollectProcMacros<'a> {
     fn visit_item(&mut self, item: &'a ast::Item) {
         if let ast::ItemKind::MacroDef(..) = item.node {
-            if self.is_proc_macro_crate && attr::contains_name(&item.attrs, "macro_export") {
+            if self.is_proc_macro_crate && attr::contains_name(&item.attrs, sym::macro_export) {
                 let msg =
                     "cannot export macro_rules! macros from a `proc-macro` crate type currently";
                 self.handler.span_err(item.span, msg);
@@ -304,11 +308,11 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
             return;
         }
 
-        if attr.check_name("proc_macro_derive") {
+        if attr.check_name(sym::proc_macro_derive) {
             self.collect_custom_derive(item, attr);
-        } else if attr.check_name("proc_macro_attribute") {
+        } else if attr.check_name(sym::proc_macro_attribute) {
             self.collect_attr_proc_macro(item);
-        } else if attr.check_name("proc_macro") {
+        } else if attr.check_name(sym::proc_macro) {
             self.collect_bang_proc_macro(item);
         };
 
diff --git a/src/libsyntax_ext/test.rs b/src/libsyntax_ext/test.rs
index 0fa5cd64360..86ae6ab5fec 100644
--- a/src/libsyntax_ext/test.rs
+++ b/src/libsyntax_ext/test.rs
@@ -7,7 +7,7 @@ use syntax::ext::hygiene::{self, Mark, SyntaxContext};
 use syntax::attr;
 use syntax::ast;
 use syntax::print::pprust;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 use syntax_pos::{DUMMY_SP, Span};
 use syntax::source_map::{ExpnInfo, MacroAttribute};
 use std::iter;
@@ -206,15 +206,15 @@ enum ShouldPanic {
 }
 
 fn should_ignore(i: &ast::Item) -> bool {
-    attr::contains_name(&i.attrs, "ignore")
+    attr::contains_name(&i.attrs, sym::ignore)
 }
 
 fn should_fail(i: &ast::Item) -> bool {
-    attr::contains_name(&i.attrs, "allow_fail")
+    attr::contains_name(&i.attrs, sym::allow_fail)
 }
 
 fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic {
-    match attr::find_by_name(&i.attrs, "should_panic") {
+    match attr::find_by_name(&i.attrs, sym::should_panic) {
         Some(attr) => {
             let ref sd = cx.parse_sess.span_diagnostic;
 
@@ -222,7 +222,7 @@ fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic {
                 // Handle #[should_panic(expected = "foo")]
                 Some(list) => {
                     let msg = list.iter()
-                        .find(|mi| mi.check_name("expected"))
+                        .find(|mi| mi.check_name(sym::expected))
                         .and_then(|mi| mi.meta_item())
                         .and_then(|mi| mi.value_str());
                     if list.len() != 1 || msg.is_none() {
@@ -247,7 +247,7 @@ fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic {
 }
 
 fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
-    let has_should_panic_attr = attr::contains_name(&i.attrs, "should_panic");
+    let has_should_panic_attr = attr::contains_name(&i.attrs, sym::should_panic);
     let ref sd = cx.parse_sess.span_diagnostic;
     if let ast::ItemKind::Fn(ref decl, ref header, ref generics, _) = i.node {
         if header.unsafety == ast::Unsafety::Unsafe {
diff --git a/src/libsyntax_ext/test_case.rs b/src/libsyntax_ext/test_case.rs
index 1ed1ab0a07b..802037f6d22 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::{self, Mark, SyntaxContext};
 use syntax::ast;
 use syntax::source_map::respan;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 use syntax_pos::{DUMMY_SP, Span};
 use syntax::source_map::{ExpnInfo, MacroAttribute};
 use syntax::feature_gate;
@@ -27,7 +27,7 @@ pub fn expand(
 ) -> Vec<Annotatable> {
     if !ecx.ecfg.enable_custom_test_frameworks() {
         feature_gate::emit_feature_err(&ecx.parse_sess,
-                                       "custom_test_frameworks",
+                                       sym::custom_test_frameworks,
                                        attr_sp,
                                        feature_gate::GateIssue::Language,
                                        feature_gate::EXPLAIN_CUSTOM_TEST_FRAMEWORKS);
diff --git a/src/libsyntax_ext/trace_macros.rs b/src/libsyntax_ext/trace_macros.rs
index 4d35daf3de9..eca658cb547 100644
--- a/src/libsyntax_ext/trace_macros.rs
+++ b/src/libsyntax_ext/trace_macros.rs
@@ -1,6 +1,6 @@
 use syntax::ext::base::{self, ExtCtxt};
 use syntax::feature_gate;
-use syntax::symbol::keywords;
+use syntax::symbol::{keywords, sym};
 use syntax_pos::Span;
 use syntax::tokenstream::TokenTree;
 
@@ -10,7 +10,7 @@ pub fn expand_trace_macros(cx: &mut ExtCtxt<'_>,
                            -> Box<dyn base::MacResult + 'static> {
     if !cx.ecfg.enable_trace_macros() {
         feature_gate::emit_feature_err(&cx.parse_sess,
-                                       "trace_macros",
+                                       sym::trace_macros,
                                        sp,
                                        feature_gate::GateIssue::Language,
                                        feature_gate::EXPLAIN_TRACE_MACROS);
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index d690a391996..c5d6da74eb6 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -33,7 +33,7 @@ mod span_encoding;
 pub use span_encoding::{Span, DUMMY_SP};
 
 pub mod symbol;
-pub use symbol::sym;
+pub use symbol::{Symbol, sym};
 
 mod analyze_source_file;
 
@@ -388,7 +388,7 @@ impl Span {
     /// Checks if a span is "internal" to a macro in which `#[unstable]`
     /// items can be used (that is, a macro marked with
     /// `#[allow_internal_unstable]`).
-    pub fn allows_unstable(&self, feature: &str) -> bool {
+    pub fn allows_unstable(&self, feature: Symbol) -> bool {
         match self.ctxt().outer().expn_info() {
             Some(info) => info
                 .allow_internal_unstable
diff --git a/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin-attr.rs b/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin-attr.rs
index 699972c9a85..c6b33fbc75e 100644
--- a/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin-attr.rs
+++ b/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin-attr.rs
@@ -14,7 +14,7 @@ use syntax::ast;
 use syntax::attr;
 use syntax::ext::base::{MultiDecorator, ExtCtxt, Annotatable};
 use syntax::ext::build::AstBuilder;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 use syntax::ptr::P;
 use syntax_ext::deriving::generic::{TraitDef, MethodDef, combine_substructure};
 use syntax_ext::deriving::generic::{Substructure, Struct, EnumMatching};
@@ -71,7 +71,7 @@ fn totalsum_substructure(cx: &mut ExtCtxt, trait_span: Span,
     };
 
     fields.iter().fold(cx.expr_isize(trait_span, 0), |acc, ref item| {
-        if attr::contains_name(&item.attrs, "ignore") {
+        if attr::contains_name(&item.attrs, sym::ignore) {
             acc
         } else {
             cx.expr_binary(item.span, ast::BinOpKind::Add, acc,
diff --git a/src/test/run-pass-fulldeps/auxiliary/issue-40001-plugin.rs b/src/test/run-pass-fulldeps/auxiliary/issue-40001-plugin.rs
index 76d0906f97c..40e0115c623 100644
--- a/src/test/run-pass-fulldeps/auxiliary/issue-40001-plugin.rs
+++ b/src/test/run-pass-fulldeps/auxiliary/issue-40001-plugin.rs
@@ -23,7 +23,7 @@ use syntax::{ast, source_map};
 #[plugin_registrar]
 pub fn plugin_registrar(reg: &mut Registry) {
     reg.register_late_lint_pass(box MissingWhitelistedAttrPass);
-    reg.register_attribute("whitelisted_attr".to_string(), Whitelisted);
+    reg.register_attribute(Symbol::intern("whitelisted_attr"), Whitelisted);
 }
 
 declare_lint! {
@@ -48,7 +48,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingWhitelistedAttrPass {
             _ => cx.tcx.hir().expect_item_by_hir_id(cx.tcx.hir().get_parent_item(id)),
         };
 
-        if !attr::contains_name(&item.attrs, "whitelisted_attr") {
+        if !attr::contains_name(&item.attrs, Symbol::intern("whitelisted_attr")) {
             cx.span_lint(MISSING_WHITELISTED_ATTR, span,
                          "Missing 'whitelisted_attr' attribute");
         }
diff --git a/src/test/run-pass-fulldeps/auxiliary/lint-for-crate.rs b/src/test/run-pass-fulldeps/auxiliary/lint-for-crate.rs
index f34e10218d4..8c7bd7222e7 100644
--- a/src/test/run-pass-fulldeps/auxiliary/lint-for-crate.rs
+++ b/src/test/run-pass-fulldeps/auxiliary/lint-for-crate.rs
@@ -11,6 +11,7 @@ use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LateLintPass
 use rustc_plugin::Registry;
 use rustc::hir;
 use syntax::attr;
+use syntax::symbol::Symbol;
 
 macro_rules! fake_lint_pass {
     ($struct:ident, $lints:expr, $($attr:expr),*) => {
@@ -49,19 +50,19 @@ declare_lint!(CRATE_NOT_GREEN, Warn, "crate not marked with #![crate_green]");
 fake_lint_pass! {
     PassOkay,
     lint_array!(CRATE_NOT_OKAY), // Single lint
-    "rustc_crate_okay"
+    Symbol::intern("rustc_crate_okay")
 }
 
 fake_lint_pass! {
     PassRedBlue,
     lint_array!(CRATE_NOT_RED, CRATE_NOT_BLUE), // Multiple lints
-    "rustc_crate_red", "rustc_crate_blue"
+    Symbol::intern("rustc_crate_red"), Symbol::intern("rustc_crate_blue")
 }
 
 fake_lint_pass! {
     PassGreyGreen,
     lint_array!(CRATE_NOT_GREY, CRATE_NOT_GREEN, ), // Trailing comma
-    "rustc_crate_grey", "rustc_crate_green"
+    Symbol::intern("rustc_crate_grey"), Symbol::intern("rustc_crate_green")
 }
 
 #[plugin_registrar]
diff --git a/src/test/ui-fulldeps/auxiliary/attr-plugin-test.rs b/src/test/ui-fulldeps/auxiliary/attr-plugin-test.rs
index c83e7bdb998..039124f31ff 100644
--- a/src/test/ui-fulldeps/auxiliary/attr-plugin-test.rs
+++ b/src/test/ui-fulldeps/auxiliary/attr-plugin-test.rs
@@ -8,14 +8,14 @@ extern crate syntax;
 extern crate rustc;
 extern crate rustc_plugin;
 
+use syntax::symbol::Symbol;
 use syntax::feature_gate::AttributeType;
 use rustc_plugin::Registry;
 
 
-
 #[plugin_registrar]
 pub fn plugin_registrar(reg: &mut Registry) {
-    reg.register_attribute("foo".to_owned(), AttributeType::Normal);
-    reg.register_attribute("bar".to_owned(), AttributeType::CrateLevel);
-    reg.register_attribute("baz".to_owned(), AttributeType::Whitelisted);
+    reg.register_attribute(Symbol::intern("foo"), AttributeType::Normal);
+    reg.register_attribute(Symbol::intern("bar"), AttributeType::CrateLevel);
+    reg.register_attribute(Symbol::intern("baz"), AttributeType::Whitelisted);
 }
diff --git a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs
index e8f1d2eedf5..7656b15721a 100644
--- a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs
+++ b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs
@@ -11,6 +11,7 @@ use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LateLintPass
 use rustc_plugin::Registry;
 use rustc::hir;
 use syntax::attr;
+use syntax::symbol::Symbol;
 
 declare_lint! {
     CRATE_NOT_OKAY,
@@ -22,7 +23,7 @@ declare_lint_pass!(Pass => [CRATE_NOT_OKAY]);
 
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
     fn check_crate(&mut self, cx: &LateContext, krate: &hir::Crate) {
-        if !attr::contains_name(&krate.attrs, "crate_okay") {
+        if !attr::contains_name(&krate.attrs, Symbol::intern("crate_okay")) {
             cx.span_lint(CRATE_NOT_OKAY, krate.span,
                          "crate is not marked with #![crate_okay]");
         }