about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-05-09 17:31:08 +0000
committerbors <bors@rust-lang.org>2020-05-09 17:31:08 +0000
commitbad3bf622bded50a97c0a54e29350eada2a3a169 (patch)
tree0cfa645b6a4e35b9c1bd6d435f44ecc1f4e2ed19
parent7c59a81a5fcbaaca311f744cd7c68d99bfbb05d3 (diff)
parent366c1786e61d14a89cebd354b78ce6a68202b699 (diff)
downloadrust-bad3bf622bded50a97c0a54e29350eada2a3a169.tar.gz
rust-bad3bf622bded50a97c0a54e29350eada2a3a169.zip
Auto merge of #72041 - RalfJung:rollup-xivrvy2, r=RalfJung
Rollup of 5 pull requests

Successful merges:

 - #69406 (upgrade chalk and use chalk-solve/chalk-ir/chalk-rust-ir)
 - #71185 (Move tests from `test/run-fail` to UI)
 - #71234 (rustllvm: Use .init_array rather than .ctors)
 - #71508 (Simplify the `tcx.alloc_map` API)
 - #71555 (Remove ast::{Ident, Name} reexports.)

Failed merges:

r? @ghost
-rw-r--r--Cargo.lock99
-rw-r--r--src/bootstrap/builder.rs2
-rw-r--r--src/bootstrap/mk/Makefile.in1
-rw-r--r--src/bootstrap/test.rs9
-rw-r--r--src/librustc_ast/ast.rs6
-rw-r--r--src/librustc_ast/attr/mod.rs6
-rw-r--r--src/librustc_ast/mut_visit.rs1
-rw-r--r--src/librustc_ast/token.rs44
-rw-r--r--src/librustc_ast/visit.rs3
-rw-r--r--src/librustc_ast_lowering/expr.rs2
-rw-r--r--src/librustc_ast_lowering/item.rs2
-rw-r--r--src/librustc_ast_lowering/lib.rs2
-rw-r--r--src/librustc_ast_lowering/pat.rs1
-rw-r--r--src/librustc_ast_lowering/path.rs1
-rw-r--r--src/librustc_ast_passes/ast_validation.rs2
-rw-r--r--src/librustc_ast_passes/feature_gate.rs4
-rw-r--r--src/librustc_ast_passes/node_count.rs1
-rw-r--r--src/librustc_ast_pretty/pprust.rs34
-rw-r--r--src/librustc_ast_pretty/pprust/tests.rs7
-rw-r--r--src/librustc_builtin_macros/assert.rs2
-rw-r--r--src/librustc_builtin_macros/concat_idents.rs6
-rw-r--r--src/librustc_builtin_macros/deriving/clone.rs5
-rw-r--r--src/librustc_builtin_macros/deriving/cmp/eq.rs4
-rw-r--r--src/librustc_builtin_macros/deriving/cmp/ord.rs8
-rw-r--r--src/librustc_builtin_macros/deriving/cmp/partial_ord.rs6
-rw-r--r--src/librustc_builtin_macros/deriving/debug.rs4
-rw-r--r--src/librustc_builtin_macros/deriving/generic/mod.rs20
-rw-r--r--src/librustc_builtin_macros/deriving/generic/ty.rs4
-rw-r--r--src/librustc_builtin_macros/deriving/mod.rs4
-rw-r--r--src/librustc_builtin_macros/env.rs4
-rw-r--r--src/librustc_builtin_macros/format.rs6
-rw-r--r--src/librustc_builtin_macros/global_allocator.rs4
-rw-r--r--src/librustc_builtin_macros/global_asm.rs3
-rw-r--r--src/librustc_builtin_macros/lib.rs3
-rw-r--r--src/librustc_builtin_macros/proc_macro_harness.rs10
-rw-r--r--src/librustc_builtin_macros/standard_library_imports.rs6
-rw-r--r--src/librustc_builtin_macros/test.rs12
-rw-r--r--src/librustc_builtin_macros/test_harness.rs4
-rw-r--r--src/librustc_codegen_llvm/back/write.rs8
-rw-r--r--src/librustc_codegen_llvm/common.rs10
-rw-r--r--src/librustc_codegen_llvm/debuginfo/metadata.rs7
-rw-r--r--src/librustc_codegen_llvm/debuginfo/mod.rs3
-rw-r--r--src/librustc_codegen_llvm/llvm/ffi.rs1
-rw-r--r--src/librustc_codegen_ssa/mir/operand.rs2
-rw-r--r--src/librustc_codegen_ssa/traits/debuginfo.rs5
-rw-r--r--src/librustc_driver/pretty.rs3
-rw-r--r--src/librustc_expand/base.rs16
-rw-r--r--src/librustc_expand/build.rs64
-rw-r--r--src/librustc_expand/expand.rs4
-rw-r--r--src/librustc_expand/mbe.rs10
-rw-r--r--src/librustc_expand/mbe/macro_parser.rs3
-rw-r--r--src/librustc_expand/mbe/macro_rules.rs16
-rw-r--r--src/librustc_expand/mbe/quoted.rs7
-rw-r--r--src/librustc_expand/module.rs14
-rw-r--r--src/librustc_expand/mut_visit/tests.rs5
-rw-r--r--src/librustc_expand/parse/tests.rs8
-rw-r--r--src/librustc_expand/placeholders.rs3
-rw-r--r--src/librustc_expand/proc_macro_server.rs4
-rw-r--r--src/librustc_expand/tokenstream/tests.rs5
-rw-r--r--src/librustc_hir/hir.rs8
-rw-r--r--src/librustc_hir/intravisit.rs7
-rw-r--r--src/librustc_hir/pat_util.rs8
-rw-r--r--src/librustc_hir_pretty/lib.rs32
-rw-r--r--src/librustc_incremental/assert_dep_graph.rs6
-rw-r--r--src/librustc_incremental/assert_module_sources.rs2
-rw-r--r--src/librustc_incremental/persist/dirty_clean.rs2
-rw-r--r--src/librustc_infer/infer/canonical/canonicalizer.rs12
-rw-r--r--src/librustc_infer/infer/mod.rs5
-rw-r--r--src/librustc_infer/traits/error_reporting/mod.rs4
-rw-r--r--src/librustc_interface/tests.rs2
-rw-r--r--src/librustc_lint/builtin.rs6
-rw-r--r--src/librustc_lint/early.rs3
-rw-r--r--src/librustc_lint/internal.rs4
-rw-r--r--src/librustc_lint/late.rs5
-rw-r--r--src/librustc_lint/lib.rs1
-rw-r--r--src/librustc_lint/non_ascii_idents.rs4
-rw-r--r--src/librustc_lint/passes.rs5
-rw-r--r--src/librustc_metadata/rmeta/decoder.rs10
-rw-r--r--src/librustc_metadata/rmeta/decoder/cstore_impl.rs4
-rw-r--r--src/librustc_metadata/rmeta/encoder.rs10
-rw-r--r--src/librustc_metadata/rmeta/mod.rs4
-rw-r--r--src/librustc_middle/Cargo.toml1
-rw-r--r--src/librustc_middle/arena.rs2
-rw-r--r--src/librustc_middle/dep_graph/dep_node.rs1
-rw-r--r--src/librustc_middle/hir/exports.rs4
-rw-r--r--src/librustc_middle/hir/map/blocks.rs3
-rw-r--r--src/librustc_middle/hir/map/mod.rs26
-rw-r--r--src/librustc_middle/ich/impls_ty.rs3
-rw-r--r--src/librustc_middle/lib.rs1
-rw-r--r--src/librustc_middle/mir/interpret/mod.rs116
-rw-r--r--src/librustc_middle/mir/mod.rs13
-rw-r--r--src/librustc_middle/query/mod.rs14
-rw-r--r--src/librustc_middle/traits/chalk.rs366
-rw-r--r--src/librustc_middle/traits/mod.rs19
-rw-r--r--src/librustc_middle/traits/specialization_graph.rs2
-rw-r--r--src/librustc_middle/ty/context.rs49
-rw-r--r--src/librustc_middle/ty/layout.rs7
-rw-r--r--src/librustc_middle/ty/mod.rs6
-rw-r--r--src/librustc_middle/ty/print/pretty.rs14
-rw-r--r--src/librustc_middle/ty/query/on_disk_cache.rs2
-rw-r--r--src/librustc_middle/ty/relate.rs5
-rw-r--r--src/librustc_middle/ty/sty.rs4
-rw-r--r--src/librustc_mir/borrow_check/mod.rs7
-rw-r--r--src/librustc_mir/const_eval/eval_queries.rs6
-rw-r--r--src/librustc_mir/interpret/intern.rs8
-rw-r--r--src/librustc_mir/interpret/memory.rs20
-rw-r--r--src/librustc_mir/interpret/operand.rs4
-rw-r--r--src/librustc_mir/interpret/place.rs2
-rw-r--r--src/librustc_mir/interpret/validity.rs2
-rw-r--r--src/librustc_mir/monomorphize/collector.rs10
-rw-r--r--src/librustc_mir/transform/mod.rs5
-rw-r--r--src/librustc_mir/util/pretty.rs3
-rw-r--r--src/librustc_mir_build/build/matches/mod.rs8
-rw-r--r--src/librustc_mir_build/hair/cx/expr.rs2
-rw-r--r--src/librustc_mir_build/hair/pattern/_match.rs4
-rw-r--r--src/librustc_mir_build/hair/pattern/mod.rs6
-rw-r--r--src/librustc_parse/parser/diagnostics.rs6
-rw-r--r--src/librustc_parse/parser/expr.rs4
-rw-r--r--src/librustc_parse/parser/item.rs8
-rw-r--r--src/librustc_parse/parser/mod.rs8
-rw-r--r--src/librustc_parse/parser/pat.rs4
-rw-r--r--src/librustc_parse/parser/path.rs4
-rw-r--r--src/librustc_passes/dead.rs6
-rw-r--r--src/librustc_passes/liveness.rs7
-rw-r--r--src/librustc_plugin_impl/load.rs4
-rw-r--r--src/librustc_privacy/Cargo.toml1
-rw-r--r--src/librustc_privacy/lib.rs3
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs7
-rw-r--r--src/librustc_resolve/diagnostics.rs4
-rw-r--r--src/librustc_resolve/imports.rs6
-rw-r--r--src/librustc_resolve/late.rs4
-rw-r--r--src/librustc_resolve/late/diagnostics.rs6
-rw-r--r--src/librustc_resolve/late/lifetimes.rs25
-rw-r--r--src/librustc_resolve/lib.rs52
-rw-r--r--src/librustc_resolve/macros.rs6
-rw-r--r--src/librustc_save_analysis/dump_visitor.rs5
-rw-r--r--src/librustc_save_analysis/lib.rs5
-rw-r--r--src/librustc_save_analysis/sig.rs15
-rw-r--r--src/librustc_session/options.rs4
-rw-r--r--src/librustc_target/spec/mod.rs7
-rw-r--r--src/librustc_target/spec/netbsd_base.rs1
-rw-r--r--src/librustc_trait_selection/traits/chalk_fulfill.rs262
-rw-r--r--src/librustc_trait_selection/traits/engine.rs10
-rw-r--r--src/librustc_trait_selection/traits/error_reporting/mod.rs21
-rw-r--r--src/librustc_trait_selection/traits/mod.rs3
-rw-r--r--src/librustc_trait_selection/traits/project.rs3
-rw-r--r--src/librustc_trait_selection/traits/select.rs14
-rw-r--r--src/librustc_traits/Cargo.toml4
-rw-r--r--src/librustc_traits/chalk/db.rs521
-rw-r--r--src/librustc_traits/chalk/lowering.rs722
-rw-r--r--src/librustc_traits/chalk/mod.rs227
-rw-r--r--src/librustc_traits/lib.rs2
-rw-r--r--src/librustc_ty/ty.rs7
-rw-r--r--src/librustc_typeck/astconv.rs19
-rw-r--r--src/librustc_typeck/check/autoderef.rs2
-rw-r--r--src/librustc_typeck/check/callee.rs2
-rw-r--r--src/librustc_typeck/check/expr.rs20
-rw-r--r--src/librustc_typeck/check/method/mod.rs14
-rw-r--r--src/librustc_typeck/check/method/probe.rs12
-rw-r--r--src/librustc_typeck/check/method/suggest.rs9
-rw-r--r--src/librustc_typeck/check/mod.rs14
-rw-r--r--src/librustc_typeck/check/op.rs2
-rw-r--r--src/librustc_typeck/check/pat.rs9
-rw-r--r--src/librustc_typeck/check/upvar.rs9
-rw-r--r--src/librustc_typeck/check/wfcheck.rs6
-rw-r--r--src/librustc_typeck/check_unused.rs5
-rw-r--r--src/librustc_typeck/collect.rs6
-rw-r--r--src/librustdoc/clean/cfg/tests.rs2
-rw-r--r--src/librustdoc/clean/inline.rs5
-rw-r--r--src/librustdoc/clean/mod.rs8
-rw-r--r--src/librustdoc/clean/types.rs4
-rw-r--r--src/librustdoc/doctree.rs43
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs4
-rw-r--r--src/librustdoc/visit_ast.rs29
-rw-r--r--src/rustllvm/PassWrapper.cpp4
-rw-r--r--src/test/run-fail/bug-811.rs24
-rw-r--r--src/test/run-fail/overflowing-lsh-1.rs9
-rw-r--r--src/test/run-fail/overflowing-lsh-2.rs9
-rw-r--r--src/test/run-fail/overflowing-lsh-3.rs9
-rw-r--r--src/test/run-fail/overflowing-rsh-1.rs9
-rw-r--r--src/test/run-fail/overflowing-rsh-2.rs9
-rw-r--r--src/test/run-fail/overflowing-rsh-3.rs9
-rw-r--r--src/test/run-fail/overflowing-rsh-5.rs9
-rw-r--r--src/test/run-fail/overflowing-rsh-6.rs10
-rw-r--r--src/test/run-fail/panic-macro-any.rs7
-rw-r--r--src/test/run-fail/unwind-unique.rs10
-rw-r--r--src/test/ui-fulldeps/pprust-expr-roundtrip.rs1
-rw-r--r--src/test/ui/array-slice-vec/bounds-check-no-overflow.rs (renamed from src/test/run-fail/bounds-check-no-overflow.rs)2
-rw-r--r--src/test/ui/array-slice-vec/dst-raw-slice.rs (renamed from src/test/run-fail/dst-raw-slice.rs)4
-rw-r--r--src/test/ui/binop/binop-fail-3.rs (renamed from src/test/run-fail/binop-fail-3.rs)4
-rw-r--r--src/test/ui/binop/binop-panic.rs (renamed from src/test/run-fail/binop-panic.rs)4
-rw-r--r--src/test/ui/borrowck/borrowck-local-borrow.rs (renamed from src/test/run-fail/borrowck-local-borrow.rs)2
-rw-r--r--src/test/ui/chalkify/basic.rs12
-rw-r--r--src/test/ui/chalkify/builtin-copy-clone.rs44
-rw-r--r--src/test/ui/chalkify/chalk_initial_program.rs16
-rw-r--r--src/test/ui/chalkify/chalk_initial_program.stderr12
-rw-r--r--src/test/ui/chalkify/generic_impls.rs18
-rw-r--r--src/test/ui/chalkify/generic_impls.stderr27
-rw-r--r--src/test/ui/chalkify/impl_wf.rs47
-rw-r--r--src/test/ui/chalkify/impl_wf.stderr12
-rw-r--r--src/test/ui/chalkify/inherent_impl.rs42
-rw-r--r--src/test/ui/chalkify/inherent_impl_min.rs27
-rw-r--r--src/test/ui/chalkify/lower_env1.rs14
-rw-r--r--src/test/ui/chalkify/lower_env2.rs16
-rw-r--r--src/test/ui/chalkify/lower_env3.rs16
-rw-r--r--src/test/ui/chalkify/lower_impl.rs17
-rw-r--r--src/test/ui/chalkify/lower_struct.rs8
-rw-r--r--src/test/ui/chalkify/lower_trait.rs11
-rw-r--r--src/test/ui/chalkify/lower_trait_higher_rank.rs9
-rw-r--r--src/test/ui/chalkify/lower_trait_where_clause.rs16
-rw-r--r--src/test/ui/chalkify/println.rs7
-rw-r--r--src/test/ui/chalkify/projection.rs25
-rw-r--r--src/test/ui/chalkify/recursive_where_clause_on_type.rs35
-rw-r--r--src/test/ui/chalkify/recursive_where_clause_on_type.stderr10
-rw-r--r--src/test/ui/chalkify/super_trait.rs19
-rw-r--r--src/test/ui/chalkify/trait_implied_bound.rs18
-rw-r--r--src/test/ui/chalkify/type_implied_bound.rs29
-rw-r--r--src/test/ui/chalkify/type_inference.rs28
-rw-r--r--src/test/ui/chalkify/type_inference.stderr12
-rw-r--r--src/test/ui/chalkify/type_wf.rs32
-rw-r--r--src/test/ui/closures/diverging-closure.rs (renamed from src/test/run-fail/diverging-closure.rs)2
-rw-r--r--src/test/ui/consts/promoted_div_by_zero.rs (renamed from src/test/run-fail/promoted_div_by_zero.rs)2
-rw-r--r--src/test/ui/fn/expr-fn-panic.rs (renamed from src/test/run-fail/expr-fn-panic.rs)2
-rw-r--r--src/test/ui/generator/generator-resume-after-panic.rs (renamed from src/test/run-fail/generator-resume-after-panic.rs)2
-rw-r--r--src/test/ui/hashmap/hashmap-capacity-overflow.rs (renamed from src/test/run-fail/hashmap-capacity-overflow.rs)2
-rw-r--r--src/test/ui/hashmap/hashmap-iter-value-lifetime.nll.stderr (renamed from src/test/ui/hashmap-iter-value-lifetime.nll.stderr)0
-rw-r--r--src/test/ui/hashmap/hashmap-iter-value-lifetime.rs (renamed from src/test/ui/hashmap-iter-value-lifetime.rs)0
-rw-r--r--src/test/ui/hashmap/hashmap-iter-value-lifetime.stderr (renamed from src/test/ui/hashmap-iter-value-lifetime.stderr)0
-rw-r--r--src/test/ui/hashmap/hashmap-lifetimes.nll.stderr (renamed from src/test/ui/hashmap-lifetimes.nll.stderr)0
-rw-r--r--src/test/ui/hashmap/hashmap-lifetimes.rs (renamed from src/test/ui/hashmap-lifetimes.rs)0
-rw-r--r--src/test/ui/hashmap/hashmap-lifetimes.stderr (renamed from src/test/ui/hashmap-lifetimes.stderr)0
-rw-r--r--src/test/ui/hashmap/hashmap-memory.rs (renamed from src/test/ui/hashmap-memory.rs)0
-rw-r--r--src/test/ui/if/expr-if-panic-fn.rs (renamed from src/test/run-fail/expr-if-panic-fn.rs)2
-rw-r--r--src/test/ui/if/expr-if-panic.rs (renamed from src/test/run-fail/expr-if-panic.rs)2
-rw-r--r--src/test/ui/if/if-check-panic.rs (renamed from src/test/run-fail/if-check-panic.rs)3
-rw-r--r--src/test/ui/if/if-cond-bot.rs (renamed from src/test/run-fail/if-cond-bot.rs)4
-rw-r--r--src/test/ui/imports/glob-use-std.rs (renamed from src/test/run-fail/glob-use-std.rs)2
-rw-r--r--src/test/ui/issues/issue-12920.rs (renamed from src/test/run-fail/issue-12920.rs)2
-rw-r--r--src/test/ui/issues/issue-13202.rs (renamed from src/test/run-fail/issue-13202.rs)2
-rw-r--r--src/test/ui/issues/issue-18576.rs (renamed from src/test/run-fail/issue-18576.rs)3
-rw-r--r--src/test/ui/issues/issue-20971.rs (renamed from src/test/run-fail/issue-20971.rs)4
-rw-r--r--src/test/ui/issues/issue-23354-2.rs (renamed from src/test/run-fail/issue-23354-2.rs)2
-rw-r--r--src/test/ui/issues/issue-23354.rs (renamed from src/test/run-fail/issue-23354.rs)2
-rw-r--r--src/test/ui/issues/issue-2444.rs (renamed from src/test/run-fail/issue-2444.rs)8
-rw-r--r--src/test/ui/issues/issue-2470-bounds-check-overflow.rs (renamed from src/test/run-fail/bug-2470-bounds-check-overflow.rs)2
-rw-r--r--src/test/ui/issues/issue-2761.rs (renamed from src/test/run-fail/issue-2761.rs)2
-rw-r--r--src/test/ui/issues/issue-28934.rs (renamed from src/test/run-fail/issue-28934.rs)2
-rw-r--r--src/test/ui/issues/issue-29798.rs (renamed from src/test/run-fail/issue-29798.rs)2
-rw-r--r--src/test/ui/issues/issue-3029.rs (renamed from src/test/run-fail/issue-3029.rs)6
-rw-r--r--src/test/ui/issues/issue-30380.rs (renamed from src/test/run-fail/issue-30380.rs)2
-rw-r--r--src/test/ui/issues/issue-44216-add-instant.rs (renamed from src/test/run-fail/issue-44216-add-instant.rs)2
-rw-r--r--src/test/ui/issues/issue-44216-add-system-time.rs (renamed from src/test/run-fail/issue-44216-add-system-time.rs)2
-rw-r--r--src/test/ui/issues/issue-44216-sub-instant.rs (renamed from src/test/run-fail/issue-44216-sub-instant.rs)2
-rw-r--r--src/test/ui/issues/issue-44216-sub-system-time.rs (renamed from src/test/run-fail/issue-44216-sub-system-time.rs)2
-rw-r--r--src/test/ui/issues/issue-51345-2.rs (renamed from src/test/run-fail/issue-51345.rs)2
-rw-r--r--src/test/ui/issues/issue-6458-1.rs (renamed from src/test/run-fail/issue-6458-1.rs)2
-rw-r--r--src/test/ui/issues/issue-811.rs26
-rw-r--r--src/test/ui/issues/issue-948.rs (renamed from src/test/run-fail/issue-948.rs)2
-rw-r--r--src/test/ui/loops/for-each-loop-panic.rs (renamed from src/test/run-fail/for-each-loop-panic.rs)2
-rw-r--r--src/test/ui/macros/assert-as-macro.rs (renamed from src/test/run-fail/assert-as-macro.rs)2
-rw-r--r--src/test/ui/macros/assert-eq-macro-panic.rs (renamed from src/test/run-fail/assert-eq-macro-panic.rs)2
-rw-r--r--src/test/ui/macros/assert-macro-explicit.rs (renamed from src/test/run-fail/assert-macro-explicit.rs)2
-rw-r--r--src/test/ui/macros/assert-macro-fmt.rs (renamed from src/test/run-fail/assert-macro-fmt.rs)2
-rw-r--r--src/test/ui/macros/assert-macro-owned.rs (renamed from src/test/run-fail/assert-macro-owned.rs)2
-rw-r--r--src/test/ui/macros/assert-macro-static.rs (renamed from src/test/run-fail/assert-macro-static.rs)2
-rw-r--r--src/test/ui/macros/assert-ne-macro-panic.rs (renamed from src/test/run-fail/assert-ne-macro-panic.rs)2
-rw-r--r--src/test/ui/macros/die-macro-2.rs (renamed from src/test/run-fail/die-macro.rs)2
-rw-r--r--src/test/ui/macros/die-macro-expr.rs (renamed from src/test/run-fail/die-macro-expr.rs)2
-rw-r--r--src/test/ui/macros/die-macro-pure.rs (renamed from src/test/run-fail/die-macro-pure.rs)2
-rw-r--r--src/test/ui/macros/unimplemented-macro-panic.rs (renamed from src/test/run-fail/unimplemented-macro-panic.rs)3
-rw-r--r--src/test/ui/macros/unreachable-fmt-msg.rs (renamed from src/test/run-fail/unreachable-fmt-msg.rs)3
-rw-r--r--src/test/ui/macros/unreachable-macro-panic.rs (renamed from src/test/run-fail/unreachable-macro-panic.rs)3
-rw-r--r--src/test/ui/macros/unreachable-static-msg.rs (renamed from src/test/run-fail/unreachable-static-msg.rs)3
-rw-r--r--src/test/ui/macros/unreachable.rs (renamed from src/test/run-fail/unreachable.rs)3
-rw-r--r--src/test/ui/match/expr-match-panic-fn.rs (renamed from src/test/run-fail/expr-match-panic-fn.rs)2
-rw-r--r--src/test/ui/match/expr-match-panic.rs (renamed from src/test/run-fail/expr-match-panic.rs)2
-rw-r--r--src/test/ui/match/match-bot-panic.rs (renamed from src/test/run-fail/match-bot-panic.rs)2
-rw-r--r--src/test/ui/match/match-disc-bot.rs (renamed from src/test/run-fail/match-disc-bot.rs)3
-rw-r--r--src/test/ui/match/match-wildcards.rs (renamed from src/test/run-fail/match-wildcards.rs)3
-rw-r--r--src/test/ui/meta-revision-bad.rs (renamed from src/test/run-fail/meta-revision-bad.rs)1
-rw-r--r--src/test/ui/meta-revision-ok.rs (renamed from src/test/run-fail/meta-revision-ok.rs)2
-rw-r--r--src/test/ui/mir/mir_codegen_calls_converging_drops.rs (renamed from src/test/run-fail/mir_codegen_calls_converging_drops.rs)2
-rw-r--r--src/test/ui/mir/mir_codegen_calls_converging_drops_2.rs (renamed from src/test/run-fail/mir_codegen_calls_converging_drops_2.rs)2
-rw-r--r--src/test/ui/mir/mir_codegen_calls_diverging.rs (renamed from src/test/run-fail/mir_codegen_calls_diverging.rs)2
-rw-r--r--src/test/ui/mir/mir_codegen_calls_diverging_drops.rs (renamed from src/test/run-fail/mir_codegen_calls_diverging_drops.rs)2
-rw-r--r--src/test/ui/mir/mir_drop_panics.rs (renamed from src/test/run-fail/mir_drop_panics.rs)2
-rw-r--r--src/test/ui/mir/mir_dynamic_drops_1.rs (renamed from src/test/run-fail/mir_dynamic_drops_1.rs)2
-rw-r--r--src/test/ui/mir/mir_dynamic_drops_2.rs (renamed from src/test/run-fail/mir_dynamic_drops_2.rs)2
-rw-r--r--src/test/ui/mir/mir_dynamic_drops_3.rs (renamed from src/test/run-fail/mir_dynamic_drops_3.rs)2
-rw-r--r--src/test/ui/mir/mir_indexing_oob_1.rs (renamed from src/test/run-fail/mir_indexing_oob_1.rs)2
-rw-r--r--src/test/ui/mir/mir_indexing_oob_2.rs (renamed from src/test/run-fail/mir_indexing_oob_2.rs)2
-rw-r--r--src/test/ui/mir/mir_indexing_oob_3.rs (renamed from src/test/run-fail/mir_indexing_oob_3.rs)2
-rw-r--r--src/test/ui/never_type/return-never-coerce.rs (renamed from src/test/run-fail/return-never-coerce.rs)2
-rw-r--r--src/test/ui/numbers-arithmetic/divide-by-zero.rs (renamed from src/test/run-fail/divide-by-zero.rs)3
-rw-r--r--src/test/ui/numbers-arithmetic/mod-zero.rs (renamed from src/test/run-fail/mod-zero.rs)3
-rw-r--r--src/test/ui/numbers-arithmetic/overflowing-add.rs (renamed from src/test/run-fail/overflowing-add.rs)2
-rw-r--r--src/test/ui/numbers-arithmetic/overflowing-lsh-1.rs9
-rw-r--r--src/test/ui/numbers-arithmetic/overflowing-lsh-1.stderr14
-rw-r--r--src/test/ui/numbers-arithmetic/overflowing-lsh-2.rs9
-rw-r--r--src/test/ui/numbers-arithmetic/overflowing-lsh-2.stderr14
-rw-r--r--src/test/ui/numbers-arithmetic/overflowing-lsh-3.rs9
-rw-r--r--src/test/ui/numbers-arithmetic/overflowing-lsh-3.stderr14
-rw-r--r--src/test/ui/numbers-arithmetic/overflowing-lsh-4.rs (renamed from src/test/run-fail/overflowing-lsh-4.rs)6
-rw-r--r--src/test/ui/numbers-arithmetic/overflowing-lsh-4.stderr14
-rw-r--r--src/test/ui/numbers-arithmetic/overflowing-mul.rs (renamed from src/test/run-fail/overflowing-mul.rs)2
-rw-r--r--src/test/ui/numbers-arithmetic/overflowing-neg.rs (renamed from src/test/run-fail/overflowing-neg.rs)2
-rw-r--r--src/test/ui/numbers-arithmetic/overflowing-pow-signed.rs (renamed from src/test/run-fail/overflowing-pow-signed.rs)2
-rw-r--r--src/test/ui/numbers-arithmetic/overflowing-pow-unsigned.rs (renamed from src/test/run-fail/overflowing-pow-unsigned.rs)2
-rw-r--r--src/test/ui/numbers-arithmetic/overflowing-rsh-1.rs9
-rw-r--r--src/test/ui/numbers-arithmetic/overflowing-rsh-1.stderr14
-rw-r--r--src/test/ui/numbers-arithmetic/overflowing-rsh-2.rs9
-rw-r--r--src/test/ui/numbers-arithmetic/overflowing-rsh-2.stderr14
-rw-r--r--src/test/ui/numbers-arithmetic/overflowing-rsh-3.rs9
-rw-r--r--src/test/ui/numbers-arithmetic/overflowing-rsh-3.stderr14
-rw-r--r--src/test/ui/numbers-arithmetic/overflowing-rsh-4.rs (renamed from src/test/run-fail/overflowing-rsh-4.rs)6
-rw-r--r--src/test/ui/numbers-arithmetic/overflowing-rsh-4.stderr14
-rw-r--r--src/test/ui/numbers-arithmetic/overflowing-rsh-5.rs9
-rw-r--r--src/test/ui/numbers-arithmetic/overflowing-rsh-5.stderr14
-rw-r--r--src/test/ui/numbers-arithmetic/overflowing-rsh-6.rs9
-rw-r--r--src/test/ui/numbers-arithmetic/overflowing-rsh-6.stderr14
-rw-r--r--src/test/ui/numbers-arithmetic/overflowing-sub.rs (renamed from src/test/run-fail/overflowing-sub.rs)2
-rw-r--r--src/test/ui/numbers-arithmetic/promoted_overflow.rs (renamed from src/test/run-fail/promoted_overflow.rs)1
-rw-r--r--src/test/ui/panic-runtime/unwind-interleaved.rs (renamed from src/test/run-fail/unwind-interleaved.rs)4
-rw-r--r--src/test/ui/panic-runtime/unwind-rec.rs (renamed from src/test/run-fail/unwind-rec.rs)5
-rw-r--r--src/test/ui/panic-runtime/unwind-rec2.rs (renamed from src/test/run-fail/unwind-rec2.rs)5
-rw-r--r--src/test/ui/panic-runtime/unwind-unique.rs12
-rw-r--r--src/test/ui/panics/args-panic.rs (renamed from src/test/run-fail/args-panic.rs)2
-rw-r--r--src/test/ui/panics/doublepanic.rs (renamed from src/test/run-fail/doublepanic.rs)3
-rw-r--r--src/test/ui/panics/explicit-panic-msg.rs (renamed from src/test/run-fail/explicit-panic-msg.rs)3
-rw-r--r--src/test/ui/panics/explicit-panic.rs (renamed from src/test/run-fail/explicit-panic.rs)3
-rw-r--r--src/test/ui/panics/fmt-panic.rs (renamed from src/test/run-fail/fmt-panic.rs)2
-rw-r--r--src/test/ui/panics/main-panic.rs (renamed from src/test/run-fail/main-panic.rs)2
-rw-r--r--src/test/ui/panics/panic-arg.rs (renamed from src/test/run-fail/panic-arg.rs)3
-rw-r--r--src/test/ui/panics/panic-macro-any-wrapped.rs (renamed from src/test/run-fail/panic-macro-any-wrapped.rs)2
-rw-r--r--src/test/ui/panics/panic-macro-any.rs9
-rw-r--r--src/test/ui/panics/panic-macro-explicit.rs (renamed from src/test/run-fail/panic-macro-explicit.rs)2
-rw-r--r--src/test/ui/panics/panic-macro-fmt.rs (renamed from src/test/run-fail/panic-macro-fmt.rs)2
-rw-r--r--src/test/ui/panics/panic-macro-owned.rs (renamed from src/test/run-fail/panic-macro-owned.rs)2
-rw-r--r--src/test/ui/panics/panic-macro-static.rs (renamed from src/test/run-fail/panic-macro-static.rs)2
-rw-r--r--src/test/ui/panics/panic-main.rs (renamed from src/test/run-fail/panic-main.rs)3
-rw-r--r--src/test/ui/panics/panic-parens.rs (renamed from src/test/run-fail/panic-parens.rs)3
-rw-r--r--src/test/ui/panics/panic-set-handler.rs (renamed from src/test/run-fail/panic-set-handler.rs)2
-rw-r--r--src/test/ui/panics/panic-set-unset-handler.rs (renamed from src/test/run-fail/panic-set-unset-handler.rs)2
-rw-r--r--src/test/ui/panics/panic-take-handler-nop.rs (renamed from src/test/run-fail/panic-take-handler-nop.rs)2
-rw-r--r--src/test/ui/panics/panic-task-name-none.rs (renamed from src/test/run-fail/panic-task-name-none.rs)1
-rw-r--r--src/test/ui/panics/panic-task-name-owned.rs (renamed from src/test/run-fail/panic-task-name-owned.rs)1
-rw-r--r--src/test/ui/panics/panic.rs (renamed from src/test/run-fail/panic.rs)3
-rw-r--r--src/test/ui/panics/result-get-panic.rs (renamed from src/test/run-fail/result-get-panic.rs)2
-rw-r--r--src/test/ui/panics/test-panic.rs (renamed from src/test/run-fail/test-panic.rs)2
-rw-r--r--src/test/ui/panics/test-should-fail-bad-message.rs (renamed from src/test/run-fail/test-should-fail-bad-message.rs)2
-rw-r--r--src/test/ui/panics/test-should-panic-bad-message.rs (renamed from src/test/run-fail/test-should-panic-bad-message.rs)5
-rw-r--r--src/test/ui/panics/test-should-panic-no-message.rs (renamed from src/test/run-fail/test-should-panic-no-message.rs)5
-rw-r--r--src/test/ui/panics/unique-panic.rs (renamed from src/test/run-fail/unique-panic.rs)1
-rw-r--r--src/test/ui/panics/while-body-panics.rs (renamed from src/test/run-fail/while-body-panics.rs)3
-rw-r--r--src/test/ui/panics/while-panic.rs (renamed from src/test/run-fail/while-panic.rs)3
-rw-r--r--src/test/ui/process/tls-exit-status.rs (renamed from src/test/run-fail/tls-exit-status.rs)2
-rw-r--r--src/test/ui/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs (renamed from src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs)2
-rw-r--r--src/test/ui/rfc-1937-termination-trait/termination-trait-for-never.rs (renamed from src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-never.rs)2
-rw-r--r--src/test/ui/rfc-1937-termination-trait/termination-trait-for-result-box-error_err.rs (renamed from src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-result-box-error_err.rs)2
-rw-r--r--src/test/ui/rfc-1937-termination-trait/termination-trait-for-str.rs (renamed from src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-str.rs)2
-rw-r--r--src/test/ui/str/str-overrun.rs (renamed from src/test/run-fail/str-overrun.rs)3
-rw-r--r--src/test/ui/structs/rhs-type.rs (renamed from src/test/run-fail/rhs-type.rs)3
-rw-r--r--src/test/ui/test-attrs/run-unexported-tests.rs (renamed from src/test/run-fail/run-unexported-tests.rs)2
-rw-r--r--src/test/ui/threads-sendsync/task-spawn-barefn.rs (renamed from src/test/run-fail/task-spawn-barefn.rs)1
-rw-r--r--src/test/ui/threads-sendsync/test-tasks-invalid-value.rs (renamed from src/test/run-fail/test-tasks-invalid-value.rs)1
-rw-r--r--src/test/ui/vec/vec-overrun.rs (renamed from src/test/run-fail/vec-overrun.rs)3
-rw-r--r--src/tools/clippy/clippy_lints/src/bytecount.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/len_zero.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/map_clone.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/non_expressive_names.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/hir_utils.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/ptr.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/usage.rs5
-rwxr-xr-xsrc/tools/clippy/util/dev7
-rw-r--r--src/tools/tidy/src/deps.rs4
380 files changed, 4111 insertions, 874 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 375e5672229..34d83e0d339 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -430,6 +430,77 @@ dependencies = [
 ]
 
 [[package]]
+name = "chalk-derive"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8d4620afad4d4d9e63f915cfa10c930b7a3c9c3ca5cd88dd771ff8e5bf04ea10"
+dependencies = [
+ "proc-macro2 1.0.3",
+ "quote 1.0.2",
+ "syn 1.0.11",
+ "synstructure 0.12.1",
+]
+
+[[package]]
+name = "chalk-engine"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ca6e5cef10197789da0b4ec310eda58da4c55530613b2323432642a97372735"
+dependencies = [
+ "chalk-macros",
+ "rustc-hash",
+]
+
+[[package]]
+name = "chalk-ir"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d45df5fb6328527f976e8a32c9e1c9970084d937ebe93d0d34f5bbf4231cb956"
+dependencies = [
+ "chalk-derive",
+ "chalk-engine",
+ "chalk-macros",
+]
+
+[[package]]
+name = "chalk-macros"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e4782d108e420a1fcf94d8a919cf248db33c5071678e87d9c2d4f20ed1feb32"
+dependencies = [
+ "lazy_static 1.4.0",
+]
+
+[[package]]
+name = "chalk-rust-ir"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a0ec96dbe0ab5fdbadfca4179ec2e1d35f0439c3b53a74988b1aec239c63eb08"
+dependencies = [
+ "chalk-derive",
+ "chalk-engine",
+ "chalk-ir",
+ "chalk-macros",
+]
+
+[[package]]
+name = "chalk-solve"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dfb99fa9530f0e101475fb60adc931f51bdea05b4642a48928b814d7f0141a6b"
+dependencies = [
+ "chalk-derive",
+ "chalk-engine",
+ "chalk-ir",
+ "chalk-macros",
+ "chalk-rust-ir",
+ "ena 0.13.1",
+ "itertools 0.9.0",
+ "petgraph",
+ "rustc-hash",
+]
+
+[[package]]
 name = "chrono"
 version = "0.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1103,6 +1174,12 @@ dependencies = [
 ]
 
 [[package]]
+name = "fixedbitset"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33"
+
+[[package]]
 name = "flate2"
 version = "1.0.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2329,6 +2406,12 @@ dependencies = [
 ]
 
 [[package]]
+name = "ordermap"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063"
+
+[[package]]
 name = "ordslice"
 version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2497,6 +2580,16 @@ dependencies = [
 ]
 
 [[package]]
+name = "petgraph"
+version = "0.4.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f"
+dependencies = [
+ "fixedbitset",
+ "ordermap",
+]
+
+[[package]]
 name = "phf"
 version = "0.7.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4002,6 +4095,7 @@ dependencies = [
  "arena",
  "bitflags",
  "byteorder",
+ "chalk-ir",
  "log",
  "measureme",
  "polonius-engine",
@@ -4132,7 +4226,6 @@ name = "rustc_privacy"
 version = "0.0.0"
 dependencies = [
  "log",
- "rustc_ast",
  "rustc_attr",
  "rustc_data_structures",
  "rustc_errors",
@@ -4301,10 +4394,14 @@ dependencies = [
 name = "rustc_traits"
 version = "0.0.0"
 dependencies = [
+ "chalk-ir",
+ "chalk-rust-ir",
+ "chalk-solve",
  "log",
  "rustc_ast",
  "rustc_data_structures",
  "rustc_hir",
+ "rustc_index",
  "rustc_infer",
  "rustc_middle",
  "rustc_span",
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 028623aa7aa..b0e06731330 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -359,7 +359,6 @@ impl<'a> Builder<'a> {
                 test::Tidy,
                 test::Ui,
                 test::CompileFail,
-                test::RunFail,
                 test::RunPassValgrind,
                 test::MirOpt,
                 test::Codegen,
@@ -370,7 +369,6 @@ impl<'a> Builder<'a> {
                 test::UiFullDeps,
                 test::Rustdoc,
                 test::Pretty,
-                test::RunFailPretty,
                 test::RunPassValgrindPretty,
                 test::Crate,
                 test::CrateLibrustc,
diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in
index e0a1f46078d..d8c97fc7414 100644
--- a/src/bootstrap/mk/Makefile.in
+++ b/src/bootstrap/mk/Makefile.in
@@ -48,7 +48,6 @@ check:
 	$(Q)$(BOOTSTRAP) test $(BOOTSTRAP_ARGS)
 check-aux:
 	$(Q)$(BOOTSTRAP) test \
-		src/test/run-fail/pretty \
 		src/test/run-pass-valgrind/pretty \
 		$(AUX_ARGS) \
 		$(BOOTSTRAP_ARGS)
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 0cf47d20ead..ad3fd0d64a3 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -898,8 +898,6 @@ default_test!(CompileFail {
     suite: "compile-fail"
 });
 
-default_test!(RunFail { path: "src/test/run-fail", mode: "run-fail", suite: "run-fail" });
-
 default_test!(RunPassValgrind {
     path: "src/test/run-pass-valgrind",
     mode: "run-pass-valgrind",
@@ -929,13 +927,6 @@ host_test!(UiFullDeps { path: "src/test/ui-fulldeps", mode: "ui", suite: "ui-ful
 host_test!(Rustdoc { path: "src/test/rustdoc", mode: "rustdoc", suite: "rustdoc" });
 
 host_test!(Pretty { path: "src/test/pretty", mode: "pretty", suite: "pretty" });
-test!(RunFailPretty {
-    path: "src/test/run-fail/pretty",
-    mode: "pretty",
-    suite: "run-fail",
-    default: false,
-    host: true
-});
 test!(RunPassValgrindPretty {
     path: "src/test/run-pass-valgrind/pretty",
     mode: "pretty",
diff --git a/src/librustc_ast/ast.rs b/src/librustc_ast/ast.rs
index c63bbd53a31..15bf4b70e2f 100644
--- a/src/librustc_ast/ast.rs
+++ b/src/librustc_ast/ast.rs
@@ -22,8 +22,6 @@ pub use crate::util::parser::ExprPrecedence;
 pub use GenericArgs::*;
 pub use UnsafeSource::*;
 
-pub use rustc_span::symbol::{Ident, Symbol as Name};
-
 use crate::ptr::P;
 use crate::token::{self, DelimToken};
 use crate::tokenstream::{DelimSpan, TokenStream, TokenTree};
@@ -34,7 +32,7 @@ use rustc_data_structures::thin_vec::ThinVec;
 use rustc_macros::HashStable_Generic;
 use rustc_serialize::{self, Decoder, Encoder};
 use rustc_span::source_map::{respan, Spanned};
-use rustc_span::symbol::{kw, sym, Symbol};
+use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{Span, DUMMY_SP};
 
 use std::convert::TryFrom;
@@ -2451,7 +2449,7 @@ pub enum ItemKind {
     /// An `extern crate` item, with the optional *original* crate name if the crate was renamed.
     ///
     /// E.g., `extern crate foo` or `extern crate foo_bar as foo`.
-    ExternCrate(Option<Name>),
+    ExternCrate(Option<Symbol>),
     /// A use declaration item (`use`).
     ///
     /// E.g., `use foo;`, `use foo::bar;` or `use foo::bar as FooBar;`.
diff --git a/src/librustc_ast/attr/mod.rs b/src/librustc_ast/attr/mod.rs
index 588d250c1bc..b812f2dadf6 100644
--- a/src/librustc_ast/attr/mod.rs
+++ b/src/librustc_ast/attr/mod.rs
@@ -3,8 +3,8 @@
 use crate::ast;
 use crate::ast::{AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute};
 use crate::ast::{Expr, GenericParam, Item, Lit, LitKind, Local, Stmt, StmtKind};
-use crate::ast::{Ident, Name, Path, PathSegment};
 use crate::ast::{MacArgs, MacDelimiter, MetaItem, MetaItemKind, NestedMetaItem};
+use crate::ast::{Path, PathSegment};
 use crate::mut_visit::visit_clobber;
 use crate::ptr::P;
 use crate::token::{self, Token};
@@ -14,7 +14,7 @@ use rustc_data_structures::sync::Lock;
 use rustc_index::bit_set::GrowableBitSet;
 use rustc_span::edition::{Edition, DEFAULT_EDITION};
 use rustc_span::source_map::{BytePos, Spanned};
-use rustc_span::symbol::{sym, Symbol};
+use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::Span;
 
 use log::debug;
@@ -113,7 +113,7 @@ impl NestedMetaItem {
     }
 
     /// Returns a name and single literal value tuple of the `MetaItem`.
-    pub fn name_value_literal(&self) -> Option<(Name, &Lit)> {
+    pub fn name_value_literal(&self) -> Option<(Symbol, &Lit)> {
         self.meta_item().and_then(|meta_item| {
             meta_item.meta_item_list().and_then(|meta_item_list| {
                 if meta_item_list.len() == 1 {
diff --git a/src/librustc_ast/mut_visit.rs b/src/librustc_ast/mut_visit.rs
index e66b358c4ac..d533aecf2df 100644
--- a/src/librustc_ast/mut_visit.rs
+++ b/src/librustc_ast/mut_visit.rs
@@ -15,6 +15,7 @@ use crate::tokenstream::*;
 use rustc_data_structures::map_in_place::MapInPlace;
 use rustc_data_structures::sync::Lrc;
 use rustc_span::source_map::{respan, Spanned};
+use rustc_span::symbol::Ident;
 use rustc_span::Span;
 
 use smallvec::{smallvec, Array, SmallVec};
diff --git a/src/librustc_ast/token.rs b/src/librustc_ast/token.rs
index be5d322ba16..a5b9c2a95bb 100644
--- a/src/librustc_ast/token.rs
+++ b/src/librustc_ast/token.rs
@@ -12,7 +12,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::sync::Lrc;
 use rustc_macros::HashStable_Generic;
 use rustc_span::symbol::kw;
-use rustc_span::symbol::Symbol;
+use rustc_span::symbol::{Ident, Symbol};
 use rustc_span::{self, Span, DUMMY_SP};
 use std::borrow::Cow;
 use std::{fmt, mem};
@@ -145,7 +145,7 @@ impl Lit {
     }
 }
 
-pub fn ident_can_begin_expr(name: ast::Name, span: Span, is_raw: bool) -> bool {
+pub fn ident_can_begin_expr(name: Symbol, span: Span, is_raw: bool) -> bool {
     let ident_token = Token::new(Ident(name, is_raw), span);
 
     !ident_token.is_reserved_ident()
@@ -173,7 +173,7 @@ pub fn ident_can_begin_expr(name: ast::Name, span: Span, is_raw: bool) -> bool {
         .contains(&name)
 }
 
-fn ident_can_begin_type(name: ast::Name, span: Span, is_raw: bool) -> bool {
+fn ident_can_begin_type(name: Symbol, span: Span, is_raw: bool) -> bool {
     let ident_token = Token::new(Ident(name, is_raw), span);
 
     !ident_token.is_reserved_ident()
@@ -229,18 +229,18 @@ pub enum TokenKind {
     /// Do not forget about `NtIdent` when you want to match on identifiers.
     /// It's recommended to use `Token::(ident,uninterpolate,uninterpolated_span)` to
     /// treat regular and interpolated identifiers in the same way.
-    Ident(ast::Name, /* is_raw */ bool),
+    Ident(Symbol, /* is_raw */ bool),
     /// Lifetime identifier token.
     /// Do not forget about `NtLifetime` when you want to match on lifetime identifiers.
     /// It's recommended to use `Token::(lifetime,uninterpolate,uninterpolated_span)` to
     /// treat regular and interpolated lifetime identifiers in the same way.
-    Lifetime(ast::Name),
+    Lifetime(Symbol),
 
     Interpolated(Lrc<Nonterminal>),
 
     // Can be expanded into several tokens.
     /// A doc comment.
-    DocComment(ast::Name),
+    DocComment(Symbol),
 
     // Junk. These carry no data because we don't really care about the data
     // they *would* carry, and don't really want to allocate a new ident for
@@ -249,9 +249,9 @@ pub enum TokenKind {
     Whitespace,
     /// A comment.
     Comment,
-    Shebang(ast::Name),
+    Shebang(Symbol),
     /// A completely invalid token which should be skipped.
-    Unknown(ast::Name),
+    Unknown(Symbol),
 
     Eof,
 }
@@ -325,8 +325,8 @@ impl Token {
         Token::new(TokenKind::Whitespace, DUMMY_SP)
     }
 
-    /// Recovers a `Token` from an `ast::Ident`. This creates a raw identifier if necessary.
-    pub fn from_ast_ident(ident: ast::Ident) -> Self {
+    /// Recovers a `Token` from an `Ident`. This creates a raw identifier if necessary.
+    pub fn from_ast_ident(ident: Ident) -> Self {
         Token::new(Ident(ident.name, ident.is_raw_guess()), ident.span)
     }
 
@@ -488,19 +488,19 @@ impl Token {
     }
 
     /// Returns an identifier if this token is an identifier.
-    pub fn ident(&self) -> Option<(ast::Ident, /* is_raw */ bool)> {
+    pub fn ident(&self) -> Option<(Ident, /* is_raw */ bool)> {
         let token = self.uninterpolate();
         match token.kind {
-            Ident(name, is_raw) => Some((ast::Ident::new(name, token.span), is_raw)),
+            Ident(name, is_raw) => Some((Ident::new(name, token.span), is_raw)),
             _ => None,
         }
     }
 
     /// Returns a lifetime identifier if this token is a lifetime.
-    pub fn lifetime(&self) -> Option<ast::Ident> {
+    pub fn lifetime(&self) -> Option<Ident> {
         let token = self.uninterpolate();
         match token.kind {
-            Lifetime(name) => Some(ast::Ident::new(name, token.span)),
+            Lifetime(name) => Some(Ident::new(name, token.span)),
             _ => None,
         }
     }
@@ -577,28 +577,28 @@ impl Token {
     }
 
     pub fn is_path_segment_keyword(&self) -> bool {
-        self.is_non_raw_ident_where(ast::Ident::is_path_segment_keyword)
+        self.is_non_raw_ident_where(Ident::is_path_segment_keyword)
     }
 
     // Returns true for reserved identifiers used internally for elided lifetimes,
     // unnamed method parameters, crate root module, error recovery etc.
     pub fn is_special_ident(&self) -> bool {
-        self.is_non_raw_ident_where(ast::Ident::is_special)
+        self.is_non_raw_ident_where(Ident::is_special)
     }
 
     /// Returns `true` if the token is a keyword used in the language.
     pub fn is_used_keyword(&self) -> bool {
-        self.is_non_raw_ident_where(ast::Ident::is_used_keyword)
+        self.is_non_raw_ident_where(Ident::is_used_keyword)
     }
 
     /// Returns `true` if the token is a keyword reserved for possible future use.
     pub fn is_unused_keyword(&self) -> bool {
-        self.is_non_raw_ident_where(ast::Ident::is_unused_keyword)
+        self.is_non_raw_ident_where(Ident::is_unused_keyword)
     }
 
     /// Returns `true` if the token is either a special identifier or a keyword.
     pub fn is_reserved_ident(&self) -> bool {
-        self.is_non_raw_ident_where(ast::Ident::is_reserved)
+        self.is_non_raw_ident_where(Ident::is_reserved)
     }
 
     /// Returns `true` if the token is the identifier `true` or `false`.
@@ -607,7 +607,7 @@ impl Token {
     }
 
     /// Returns `true` if the token is a non-raw identifier for which `pred` holds.
-    pub fn is_non_raw_ident_where(&self, pred: impl FnOnce(ast::Ident) -> bool) -> bool {
+    pub fn is_non_raw_ident_where(&self, pred: impl FnOnce(Ident) -> bool) -> bool {
         match self.ident() {
             Some((id, false)) => pred(id),
             _ => false,
@@ -746,8 +746,8 @@ pub enum Nonterminal {
     NtPat(P<ast::Pat>),
     NtExpr(P<ast::Expr>),
     NtTy(P<ast::Ty>),
-    NtIdent(ast::Ident, /* is_raw */ bool),
-    NtLifetime(ast::Ident),
+    NtIdent(Ident, /* is_raw */ bool),
+    NtLifetime(Ident),
     NtLiteral(P<ast::Expr>),
     /// Stuff inside brackets for attributes
     NtMeta(P<ast::AttrItem>),
diff --git a/src/librustc_ast/visit.rs b/src/librustc_ast/visit.rs
index 51863350a8c..63f483663bf 100644
--- a/src/librustc_ast/visit.rs
+++ b/src/librustc_ast/visit.rs
@@ -17,6 +17,7 @@ use crate::ast::*;
 use crate::token::Token;
 use crate::tokenstream::{TokenStream, TokenTree};
 
+use rustc_span::symbol::{Ident, Symbol};
 use rustc_span::Span;
 
 #[derive(Copy, Clone, PartialEq)]
@@ -74,7 +75,7 @@ impl<'a> FnKind<'a> {
 /// to monitor future changes to `Visitor` in case a new method with a
 /// new default implementation gets introduced.)
 pub trait Visitor<'ast>: Sized {
-    fn visit_name(&mut self, _span: Span, _name: Name) {
+    fn visit_name(&mut self, _span: Span, _name: Symbol) {
         // Nothing to do.
     }
     fn visit_ident(&mut self, ident: Ident) {
diff --git a/src/librustc_ast_lowering/expr.rs b/src/librustc_ast_lowering/expr.rs
index 251faf6af00..8da3aa633b8 100644
--- a/src/librustc_ast_lowering/expr.rs
+++ b/src/librustc_ast_lowering/expr.rs
@@ -9,7 +9,7 @@ use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_hir::def::Res;
 use rustc_span::source_map::{respan, DesugaringKind, Span, Spanned};
-use rustc_span::symbol::{sym, Symbol};
+use rustc_span::symbol::{sym, Ident, Symbol};
 
 impl<'hir> LoweringContext<'_, 'hir> {
     fn lower_exprs(&mut self, exprs: &[AstP<Expr>]) -> &'hir [hir::Expr<'hir>] {
diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs
index c535885e70c..eced17c9245 100644
--- a/src/librustc_ast_lowering/item.rs
+++ b/src/librustc_ast_lowering/item.rs
@@ -12,7 +12,7 @@ use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::LocalDefId;
 use rustc_span::source_map::{respan, DesugaringKind};
-use rustc_span::symbol::{kw, sym};
+use rustc_span::symbol::{kw, sym, Ident};
 use rustc_span::Span;
 use rustc_target::spec::abi;
 
diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs
index 47dd757823b..7e6dfbf00f5 100644
--- a/src/librustc_ast_lowering/lib.rs
+++ b/src/librustc_ast_lowering/lib.rs
@@ -63,7 +63,7 @@ use rustc_session::parse::ParseSess;
 use rustc_session::Session;
 use rustc_span::hygiene::ExpnId;
 use rustc_span::source_map::{respan, DesugaringKind, ExpnData, ExpnKind};
-use rustc_span::symbol::{kw, sym, Symbol};
+use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::Span;
 
 use log::{debug, trace};
diff --git a/src/librustc_ast_lowering/pat.rs b/src/librustc_ast_lowering/pat.rs
index d54ad2036d5..496e401d061 100644
--- a/src/librustc_ast_lowering/pat.rs
+++ b/src/librustc_ast_lowering/pat.rs
@@ -5,6 +5,7 @@ use rustc_ast::ptr::P;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_hir as hir;
 use rustc_hir::def::Res;
+use rustc_span::symbol::Ident;
 use rustc_span::{source_map::Spanned, Span};
 
 impl<'a, 'hir> LoweringContext<'a, 'hir> {
diff --git a/src/librustc_ast_lowering/path.rs b/src/librustc_ast_lowering/path.rs
index cf6dde81309..e5ce51f8d2d 100644
--- a/src/librustc_ast_lowering/path.rs
+++ b/src/librustc_ast_lowering/path.rs
@@ -9,6 +9,7 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::GenericArg;
 use rustc_session::lint::builtin::ELIDED_LIFETIMES_IN_PATHS;
 use rustc_session::lint::BuiltinLintDiagnostics;
+use rustc_span::symbol::Ident;
 use rustc_span::Span;
 
 use log::debug;
diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs
index cc88fbb295c..46c415413e9 100644
--- a/src/librustc_ast_passes/ast_validation.rs
+++ b/src/librustc_ast_passes/ast_validation.rs
@@ -20,7 +20,7 @@ use rustc_parse::validate_attr;
 use rustc_session::lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY;
 use rustc_session::lint::LintBuffer;
 use rustc_session::Session;
-use rustc_span::symbol::{kw, sym};
+use rustc_span::symbol::{kw, sym, Ident};
 use rustc_span::Span;
 use std::mem;
 use std::ops::DerefMut;
diff --git a/src/librustc_ast_passes/feature_gate.rs b/src/librustc_ast_passes/feature_gate.rs
index 76c790f80b8..ffd741a7b37 100644
--- a/src/librustc_ast_passes/feature_gate.rs
+++ b/src/librustc_ast_passes/feature_gate.rs
@@ -7,7 +7,7 @@ use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP};
 use rustc_feature::{Features, GateIssue, UnstableFeatures};
 use rustc_session::parse::{feature_err, feature_err_issue, ParseSess};
 use rustc_span::source_map::Spanned;
-use rustc_span::symbol::sym;
+use rustc_span::symbol::{sym, Symbol};
 use rustc_span::Span;
 
 use log::debug;
@@ -252,7 +252,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
         }
     }
 
-    fn visit_name(&mut self, sp: Span, name: ast::Name) {
+    fn visit_name(&mut self, sp: Span, name: Symbol) {
         if !name.as_str().is_ascii() {
             gate_feature_post!(
                 &self,
diff --git a/src/librustc_ast_passes/node_count.rs b/src/librustc_ast_passes/node_count.rs
index 534d6c7b1ea..3cf562b927e 100644
--- a/src/librustc_ast_passes/node_count.rs
+++ b/src/librustc_ast_passes/node_count.rs
@@ -2,6 +2,7 @@
 
 use rustc_ast::ast::*;
 use rustc_ast::visit::*;
+use rustc_span::symbol::Ident;
 use rustc_span::Span;
 
 pub struct NodeCounter {
diff --git a/src/librustc_ast_pretty/pprust.rs b/src/librustc_ast_pretty/pprust.rs
index d3d7f486b47..e6803fdd7f1 100644
--- a/src/librustc_ast_pretty/pprust.rs
+++ b/src/librustc_ast_pretty/pprust.rs
@@ -12,7 +12,7 @@ use rustc_ast::util::parser::{self, AssocOp, Fixity};
 use rustc_ast::util::{classify, comments};
 use rustc_span::edition::Edition;
 use rustc_span::source_map::{SourceMap, Spanned};
-use rustc_span::symbol::{kw, sym, IdentPrinter};
+use rustc_span::symbol::{kw, sym, Ident, IdentPrinter, Symbol};
 use rustc_span::{BytePos, FileName, Span};
 
 use std::borrow::Cow;
@@ -26,8 +26,8 @@ pub enum MacHeader<'a> {
 }
 
 pub enum AnnNode<'a> {
-    Ident(&'a ast::Ident),
-    Name(&'a ast::Name),
+    Ident(&'a Ident),
+    Name(&'a Symbol),
     Block(&'a ast::Block),
     Item(&'a ast::Item),
     SubItem(ast::NodeId),
@@ -118,8 +118,8 @@ pub fn print_crate<'a>(
         // of the feature gate, so we fake them up here.
 
         // `#![feature(prelude_import)]`
-        let pi_nested = attr::mk_nested_word_item(ast::Ident::with_dummy_span(sym::prelude_import));
-        let list = attr::mk_list_item(ast::Ident::with_dummy_span(sym::feature), vec![pi_nested]);
+        let pi_nested = attr::mk_nested_word_item(Ident::with_dummy_span(sym::prelude_import));
+        let list = attr::mk_list_item(Ident::with_dummy_span(sym::feature), vec![pi_nested]);
         let fake_attr = attr::mk_attr_inner(list);
         s.print_attribute(&fake_attr);
 
@@ -127,7 +127,7 @@ pub fn print_crate<'a>(
         // root, so this is not needed, and actually breaks things.
         if edition == Edition::Edition2015 {
             // `#![no_std]`
-            let no_std_meta = attr::mk_word_item(ast::Ident::with_dummy_span(sym::no_std));
+            let no_std_meta = attr::mk_word_item(Ident::with_dummy_span(sym::no_std));
             let fake_attr = attr::mk_attr_inner(no_std_meta);
             s.print_attribute(&fake_attr);
         }
@@ -389,7 +389,7 @@ impl std::ops::DerefMut for State<'_> {
 
 pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::DerefMut {
     fn comments(&mut self) -> &mut Option<Comments<'a>>;
-    fn print_ident(&mut self, ident: ast::Ident);
+    fn print_ident(&mut self, ident: Ident);
     fn print_generic_args(&mut self, args: &ast::GenericArgs, colons_before_params: bool);
 
     fn strsep<T, F>(
@@ -671,7 +671,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
         &mut self,
         header: Option<MacHeader<'_>>,
         has_bang: bool,
-        ident: Option<ast::Ident>,
+        ident: Option<Ident>,
         delim: DelimToken,
         tts: TokenStream,
         convert_dollar_crate: bool,
@@ -782,7 +782,7 @@ impl<'a> PrintState<'a> for State<'a> {
         &mut self.comments
     }
 
-    fn print_ident(&mut self, ident: ast::Ident) {
+    fn print_ident(&mut self, ident: Ident) {
         self.s.word(IdentPrinter::for_ast_ident(ident, ident.is_raw_guess()).to_string());
         self.ann.post(self, AnnNode::Ident(&ident))
     }
@@ -1001,7 +1001,7 @@ impl<'a> State<'a> {
 
     fn print_item_const(
         &mut self,
-        ident: ast::Ident,
+        ident: Ident,
         mutbl: Option<ast::Mutability>,
         ty: &ast::Ty,
         body: Option<&ast::Expr>,
@@ -1032,7 +1032,7 @@ impl<'a> State<'a> {
 
     fn print_associated_type(
         &mut self,
-        ident: ast::Ident,
+        ident: Ident,
         generics: &ast::Generics,
         bounds: &ast::GenericBounds,
         ty: Option<&ast::Ty>,
@@ -1281,7 +1281,7 @@ impl<'a> State<'a> {
         &mut self,
         enum_definition: &ast::EnumDef,
         generics: &ast::Generics,
-        ident: ast::Ident,
+        ident: Ident,
         span: rustc_span::Span,
         visibility: &ast::Visibility,
     ) {
@@ -1337,7 +1337,7 @@ impl<'a> State<'a> {
         &mut self,
         struct_def: &ast::VariantData,
         generics: &ast::Generics,
-        ident: ast::Ident,
+        ident: Ident,
         span: rustc_span::Span,
         print_finalizer: bool,
     ) {
@@ -2116,7 +2116,7 @@ impl<'a> State<'a> {
         self.s.word(i.to_string())
     }
 
-    crate fn print_name(&mut self, name: ast::Name) {
+    crate fn print_name(&mut self, name: Symbol) {
         self.s.word(name.to_string());
         self.ann.post(self, AnnNode::Name(&name))
     }
@@ -2322,7 +2322,7 @@ impl<'a> State<'a> {
     fn print_fn_full(
         &mut self,
         sig: &ast::FnSig,
-        name: ast::Ident,
+        name: Ident,
         generics: &ast::Generics,
         vis: &ast::Visibility,
         defaultness: ast::Defaultness,
@@ -2347,7 +2347,7 @@ impl<'a> State<'a> {
         &mut self,
         decl: &ast::FnDecl,
         header: ast::FnHeader,
-        name: Option<ast::Ident>,
+        name: Option<Ident>,
         generics: &ast::Generics,
     ) {
         self.print_fn_header_info(header);
@@ -2614,7 +2614,7 @@ impl<'a> State<'a> {
         ext: ast::Extern,
         unsafety: ast::Unsafe,
         decl: &ast::FnDecl,
-        name: Option<ast::Ident>,
+        name: Option<Ident>,
         generic_params: &[ast::GenericParam],
     ) {
         self.ibox(INDENT_UNIT);
diff --git a/src/librustc_ast_pretty/pprust/tests.rs b/src/librustc_ast_pretty/pprust/tests.rs
index 455f2e3da36..f51439f89ff 100644
--- a/src/librustc_ast_pretty/pprust/tests.rs
+++ b/src/librustc_ast_pretty/pprust/tests.rs
@@ -4,11 +4,12 @@ use rustc_ast::ast;
 use rustc_ast::with_default_globals;
 use rustc_span;
 use rustc_span::source_map::respan;
+use rustc_span::symbol::Ident;
 
 fn fun_to_string(
     decl: &ast::FnDecl,
     header: ast::FnHeader,
-    name: ast::Ident,
+    name: Ident,
     generics: &ast::Generics,
 ) -> String {
     to_string(|s| {
@@ -26,7 +27,7 @@ fn variant_to_string(var: &ast::Variant) -> String {
 #[test]
 fn test_fun_to_string() {
     with_default_globals(|| {
-        let abba_ident = ast::Ident::from_str("abba");
+        let abba_ident = Ident::from_str("abba");
 
         let decl =
             ast::FnDecl { inputs: Vec::new(), output: ast::FnRetTy::Default(rustc_span::DUMMY_SP) };
@@ -41,7 +42,7 @@ fn test_fun_to_string() {
 #[test]
 fn test_variant_to_string() {
     with_default_globals(|| {
-        let ident = ast::Ident::from_str("principal_skinner");
+        let ident = Ident::from_str("principal_skinner");
 
         let var = ast::Variant {
             ident,
diff --git a/src/librustc_builtin_macros/assert.rs b/src/librustc_builtin_macros/assert.rs
index 3a3595b04d2..166cd628350 100644
--- a/src/librustc_builtin_macros/assert.rs
+++ b/src/librustc_builtin_macros/assert.rs
@@ -7,7 +7,7 @@ use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
 use rustc_ast_pretty::pprust;
 use rustc_expand::base::*;
 use rustc_parse::parser::Parser;
-use rustc_span::symbol::{sym, Symbol};
+use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::{Span, DUMMY_SP};
 
 pub fn expand_assert<'cx>(
diff --git a/src/librustc_builtin_macros/concat_idents.rs b/src/librustc_builtin_macros/concat_idents.rs
index b55e71b2518..8a1741c0654 100644
--- a/src/librustc_builtin_macros/concat_idents.rs
+++ b/src/librustc_builtin_macros/concat_idents.rs
@@ -3,7 +3,7 @@ use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Token};
 use rustc_ast::tokenstream::{TokenStream, TokenTree};
 use rustc_expand::base::{self, *};
-use rustc_span::symbol::Symbol;
+use rustc_span::symbol::{Ident, Symbol};
 use rustc_span::Span;
 
 pub fn expand_concat_idents<'cx>(
@@ -39,10 +39,10 @@ pub fn expand_concat_idents<'cx>(
         }
     }
 
-    let ident = ast::Ident::new(Symbol::intern(&res_str), cx.with_call_site_ctxt(sp));
+    let ident = Ident::new(Symbol::intern(&res_str), cx.with_call_site_ctxt(sp));
 
     struct ConcatIdentsResult {
-        ident: ast::Ident,
+        ident: Ident,
     }
 
     impl base::MacResult for ConcatIdentsResult {
diff --git a/src/librustc_builtin_macros/deriving/clone.rs b/src/librustc_builtin_macros/deriving/clone.rs
index 97569ef8138..5dbf3825ce6 100644
--- a/src/librustc_builtin_macros/deriving/clone.rs
+++ b/src/librustc_builtin_macros/deriving/clone.rs
@@ -5,7 +5,7 @@ use crate::deriving::path_std;
 use rustc_ast::ast::{self, Expr, GenericArg, Generics, ItemKind, MetaItem, VariantData};
 use rustc_ast::ptr::P;
 use rustc_expand::base::{Annotatable, ExtCtxt};
-use rustc_span::symbol::{kw, sym, Symbol};
+use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::Span;
 
 pub fn expand_deriving_clone(
@@ -135,8 +135,7 @@ fn cs_clone_shallow(
     let mut stmts = Vec::new();
     if is_union {
         // let _: AssertParamIsCopy<Self>;
-        let self_ty =
-            cx.ty_path(cx.path_ident(trait_span, ast::Ident::with_dummy_span(kw::SelfUpper)));
+        let self_ty = cx.ty_path(cx.path_ident(trait_span, Ident::with_dummy_span(kw::SelfUpper)));
         assert_ty_bounds(cx, &mut stmts, self_ty, trait_span, "AssertParamIsCopy");
     } else {
         match *substr.fields {
diff --git a/src/librustc_builtin_macros/deriving/cmp/eq.rs b/src/librustc_builtin_macros/deriving/cmp/eq.rs
index b39f41513ee..b3b15b89782 100644
--- a/src/librustc_builtin_macros/deriving/cmp/eq.rs
+++ b/src/librustc_builtin_macros/deriving/cmp/eq.rs
@@ -2,10 +2,10 @@ use crate::deriving::generic::ty::*;
 use crate::deriving::generic::*;
 use crate::deriving::path_std;
 
-use rustc_ast::ast::{self, Expr, GenericArg, Ident, MetaItem};
+use rustc_ast::ast::{self, Expr, GenericArg, MetaItem};
 use rustc_ast::ptr::P;
 use rustc_expand::base::{Annotatable, ExtCtxt};
-use rustc_span::symbol::{sym, Symbol};
+use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::Span;
 
 pub fn expand_deriving_eq(
diff --git a/src/librustc_builtin_macros/deriving/cmp/ord.rs b/src/librustc_builtin_macros/deriving/cmp/ord.rs
index b23fbc6f62b..030d2c83742 100644
--- a/src/librustc_builtin_macros/deriving/cmp/ord.rs
+++ b/src/librustc_builtin_macros/deriving/cmp/ord.rs
@@ -5,7 +5,7 @@ use crate::deriving::path_std;
 use rustc_ast::ast::{self, Expr, MetaItem};
 use rustc_ast::ptr::P;
 use rustc_expand::base::{Annotatable, ExtCtxt};
-use rustc_span::symbol::sym;
+use rustc_span::symbol::{sym, Ident};
 use rustc_span::Span;
 
 pub fn expand_deriving_ord(
@@ -45,15 +45,15 @@ pub fn expand_deriving_ord(
 pub fn ordering_collapsed(
     cx: &mut ExtCtxt<'_>,
     span: Span,
-    self_arg_tags: &[ast::Ident],
+    self_arg_tags: &[Ident],
 ) -> P<ast::Expr> {
     let lft = cx.expr_ident(span, self_arg_tags[0]);
     let rgt = cx.expr_addr_of(span, cx.expr_ident(span, self_arg_tags[1]));
-    cx.expr_method_call(span, lft, ast::Ident::new(sym::cmp, span), vec![rgt])
+    cx.expr_method_call(span, lft, Ident::new(sym::cmp, span), vec![rgt])
 }
 
 pub fn cs_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P<Expr> {
-    let test_id = ast::Ident::new(sym::cmp, span);
+    let test_id = Ident::new(sym::cmp, span);
     let equals_path = cx.path_global(span, cx.std_path(&[sym::cmp, sym::Ordering, sym::Equal]));
 
     let cmp_path = cx.std_path(&[sym::cmp, sym::Ord, sym::cmp]);
diff --git a/src/librustc_builtin_macros/deriving/cmp/partial_ord.rs b/src/librustc_builtin_macros/deriving/cmp/partial_ord.rs
index 835ccd1b022..f29f91e8231 100644
--- a/src/librustc_builtin_macros/deriving/cmp/partial_ord.rs
+++ b/src/librustc_builtin_macros/deriving/cmp/partial_ord.rs
@@ -7,7 +7,7 @@ use crate::deriving::{path_local, path_std, pathvec_std};
 use rustc_ast::ast::{self, BinOpKind, Expr, MetaItem};
 use rustc_ast::ptr::P;
 use rustc_expand::base::{Annotatable, ExtCtxt};
-use rustc_span::symbol::{sym, Symbol};
+use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::Span;
 
 pub fn expand_deriving_partial_ord(
@@ -104,7 +104,7 @@ pub fn some_ordering_collapsed(
     cx: &mut ExtCtxt<'_>,
     span: Span,
     op: OrderingOp,
-    self_arg_tags: &[ast::Ident],
+    self_arg_tags: &[Ident],
 ) -> P<ast::Expr> {
     let lft = cx.expr_ident(span, self_arg_tags[0]);
     let rgt = cx.expr_addr_of(span, cx.expr_ident(span, self_arg_tags[1]));
@@ -119,7 +119,7 @@ pub fn some_ordering_collapsed(
 }
 
 pub fn cs_partial_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P<Expr> {
-    let test_id = ast::Ident::new(sym::cmp, span);
+    let test_id = Ident::new(sym::cmp, span);
     let ordering = cx.path_global(span, cx.std_path(&[sym::cmp, sym::Ordering, sym::Equal]));
     let ordering_expr = cx.expr_path(ordering.clone());
     let equals_expr = cx.expr_some(span, ordering_expr);
diff --git a/src/librustc_builtin_macros/deriving/debug.rs b/src/librustc_builtin_macros/deriving/debug.rs
index cea7e8176b6..99c2b6f8a4e 100644
--- a/src/librustc_builtin_macros/deriving/debug.rs
+++ b/src/librustc_builtin_macros/deriving/debug.rs
@@ -2,11 +2,11 @@ use crate::deriving::generic::ty::*;
 use crate::deriving::generic::*;
 use crate::deriving::path_std;
 
-use rustc_ast::ast::{self, Ident};
+use rustc_ast::ast;
 use rustc_ast::ast::{Expr, MetaItem};
 use rustc_ast::ptr::P;
 use rustc_expand::base::{Annotatable, ExtCtxt};
-use rustc_span::symbol::sym;
+use rustc_span::symbol::{sym, Ident};
 use rustc_span::{Span, DUMMY_SP};
 
 pub fn expand_deriving_debug(
diff --git a/src/librustc_builtin_macros/deriving/generic/mod.rs b/src/librustc_builtin_macros/deriving/generic/mod.rs
index 3a96c5aa8ed..0ba9df08383 100644
--- a/src/librustc_builtin_macros/deriving/generic/mod.rs
+++ b/src/librustc_builtin_macros/deriving/generic/mod.rs
@@ -181,7 +181,7 @@ use std::cell::RefCell;
 use std::iter;
 use std::vec;
 
-use rustc_ast::ast::{self, BinOpKind, EnumDef, Expr, Generics, Ident, PatKind};
+use rustc_ast::ast::{self, BinOpKind, EnumDef, Expr, Generics, PatKind};
 use rustc_ast::ast::{GenericArg, GenericParamKind, VariantData};
 use rustc_ast::ptr::P;
 use rustc_attr as attr;
@@ -189,7 +189,7 @@ use rustc_data_structures::map_in_place::MapInPlace;
 use rustc_expand::base::{Annotatable, ExtCtxt};
 use rustc_session::parse::ParseSess;
 use rustc_span::source_map::respan;
-use rustc_span::symbol::{kw, sym, Symbol};
+use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::Span;
 
 use ty::{LifetimeBounds, Path, Ptr, PtrTy, Self_, Ty};
@@ -222,7 +222,7 @@ pub struct TraitDef<'a> {
 
     pub methods: Vec<MethodDef<'a>>,
 
-    pub associated_types: Vec<(ast::Ident, Ty<'a>)>,
+    pub associated_types: Vec<(Ident, Ty<'a>)>,
 }
 
 pub struct MethodDef<'a> {
@@ -336,14 +336,14 @@ pub fn combine_substructure(
 /// is not global and starts with `T`, or a `TyQPath`.
 fn find_type_parameters(
     ty: &ast::Ty,
-    ty_param_names: &[ast::Name],
+    ty_param_names: &[Symbol],
     cx: &ExtCtxt<'_>,
 ) -> Vec<P<ast::Ty>> {
     use rustc_ast::visit;
 
     struct Visitor<'a, 'b> {
         cx: &'a ExtCtxt<'b>,
-        ty_param_names: &'a [ast::Name],
+        ty_param_names: &'a [Symbol],
         types: Vec<P<ast::Ty>>,
     }
 
@@ -620,7 +620,7 @@ impl<'a> TraitDef<'a> {
                 .peekable();
 
             if ty_params.peek().is_some() {
-                let ty_param_names: Vec<ast::Name> =
+                let ty_param_names: Vec<Symbol> =
                     ty_params.map(|ty_param| ty_param.ident.name).collect();
 
                 for field_ty in field_tys {
@@ -1223,7 +1223,7 @@ impl<'a> MethodDef<'a> {
             .collect::<Vec<String>>();
 
         let self_arg_idents =
-            self_arg_names.iter().map(|name| cx.ident_of(name, sp)).collect::<Vec<ast::Ident>>();
+            self_arg_names.iter().map(|name| cx.ident_of(name, sp)).collect::<Vec<Ident>>();
 
         // The `vi_idents` will be bound, solely in the catch-all, to
         // a series of let statements mapping each self_arg to an int
@@ -1234,7 +1234,7 @@ impl<'a> MethodDef<'a> {
                 let vi_suffix = format!("{}_vi", &name[..]);
                 cx.ident_of(&vi_suffix[..], trait_.span)
             })
-            .collect::<Vec<ast::Ident>>();
+            .collect::<Vec<Ident>>();
 
         // Builds, via callback to call_substructure_method, the
         // delegated expression that handles the catch-all case,
@@ -1598,7 +1598,7 @@ impl<'a> TraitDef<'a> {
     fn create_subpatterns(
         &self,
         cx: &mut ExtCtxt<'_>,
-        field_paths: Vec<ast::Ident>,
+        field_paths: Vec<Ident>,
         mutbl: ast::Mutability,
         use_temporaries: bool,
     ) -> Vec<P<ast::Pat>> {
@@ -1670,7 +1670,7 @@ impl<'a> TraitDef<'a> {
     fn create_enum_variant_pattern(
         &self,
         cx: &mut ExtCtxt<'_>,
-        enum_ident: ast::Ident,
+        enum_ident: Ident,
         variant: &'a ast::Variant,
         prefix: &str,
         mutbl: ast::Mutability,
diff --git a/src/librustc_builtin_macros/deriving/generic/ty.rs b/src/librustc_builtin_macros/deriving/generic/ty.rs
index 23980a2db8d..62cbdb19a88 100644
--- a/src/librustc_builtin_macros/deriving/generic/ty.rs
+++ b/src/librustc_builtin_macros/deriving/generic/ty.rs
@@ -4,11 +4,11 @@
 pub use PtrTy::*;
 pub use Ty::*;
 
-use rustc_ast::ast::{self, Expr, GenericArg, GenericParamKind, Generics, Ident, SelfKind};
+use rustc_ast::ast::{self, Expr, GenericArg, GenericParamKind, Generics, SelfKind};
 use rustc_ast::ptr::P;
 use rustc_expand::base::ExtCtxt;
 use rustc_span::source_map::{respan, DUMMY_SP};
-use rustc_span::symbol::kw;
+use rustc_span::symbol::{kw, Ident};
 use rustc_span::Span;
 
 /// The types of pointers
diff --git a/src/librustc_builtin_macros/deriving/mod.rs b/src/librustc_builtin_macros/deriving/mod.rs
index b5ad67abf62..9660cade382 100644
--- a/src/librustc_builtin_macros/deriving/mod.rs
+++ b/src/librustc_builtin_macros/deriving/mod.rs
@@ -3,7 +3,7 @@
 use rustc_ast::ast::{self, ItemKind, MetaItem};
 use rustc_ast::ptr::P;
 use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, MultiItemModifier};
-use rustc_span::symbol::{sym, Symbol};
+use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::Span;
 
 macro path_local($x:ident) {
@@ -154,7 +154,7 @@ fn inject_impl_of_structural_trait(
 
     let newitem = cx.item(
         span,
-        ast::Ident::invalid(),
+        Ident::invalid(),
         attrs,
         ItemKind::Impl {
             unsafety: ast::Unsafe::No,
diff --git a/src/librustc_builtin_macros/env.rs b/src/librustc_builtin_macros/env.rs
index fba76f8b496..21e1889513b 100644
--- a/src/librustc_builtin_macros/env.rs
+++ b/src/librustc_builtin_macros/env.rs
@@ -3,10 +3,10 @@
 // interface.
 //
 
-use rustc_ast::ast::{self, GenericArg, Ident};
+use rustc_ast::ast::{self, GenericArg};
 use rustc_ast::tokenstream::TokenStream;
 use rustc_expand::base::{self, *};
-use rustc_span::symbol::{kw, sym, Symbol};
+use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::Span;
 
 use std::env;
diff --git a/src/librustc_builtin_macros/format.rs b/src/librustc_builtin_macros/format.rs
index 595254700e3..efce6288198 100644
--- a/src/librustc_builtin_macros/format.rs
+++ b/src/librustc_builtin_macros/format.rs
@@ -10,7 +10,7 @@ use rustc_ast::tokenstream::TokenStream;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::{pluralize, Applicability, DiagnosticBuilder};
 use rustc_expand::base::{self, *};
-use rustc_span::symbol::{sym, Symbol};
+use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::{MultiSpan, Span};
 
 use std::borrow::Cow;
@@ -535,7 +535,7 @@ impl<'a, 'b> Context<'a, 'b> {
         self.count_args_index_offset = sofar;
     }
 
-    fn rtpath(ecx: &ExtCtxt<'_>, s: &str) -> Vec<ast::Ident> {
+    fn rtpath(ecx: &ExtCtxt<'_>, s: &str) -> Vec<Ident> {
         ecx.std_path(&[sym::fmt, sym::rt, sym::v1, Symbol::intern(s)])
     }
 
@@ -794,7 +794,7 @@ impl<'a, 'b> Context<'a, 'b> {
         macsp: Span,
         mut sp: Span,
         ty: &ArgumentType,
-        arg: ast::Ident,
+        arg: Ident,
     ) -> P<ast::Expr> {
         sp = ecx.with_def_site_ctxt(sp);
         let arg = ecx.expr_ident(sp, arg);
diff --git a/src/librustc_builtin_macros/global_allocator.rs b/src/librustc_builtin_macros/global_allocator.rs
index 5d16be3206a..feda17c1812 100644
--- a/src/librustc_builtin_macros/global_allocator.rs
+++ b/src/librustc_builtin_macros/global_allocator.rs
@@ -1,13 +1,13 @@
 use crate::util::check_builtin_macro_attribute;
 
-use rustc_ast::ast::{self, Attribute, Expr, FnHeader, FnSig, Generics, Ident, Param};
+use rustc_ast::ast::{self, Attribute, Expr, FnHeader, FnSig, Generics, Param};
 use rustc_ast::ast::{ItemKind, Mutability, Stmt, Ty, TyKind, Unsafe};
 use rustc_ast::expand::allocator::{
     AllocatorKind, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS,
 };
 use rustc_ast::ptr::P;
 use rustc_expand::base::{Annotatable, ExtCtxt};
-use rustc_span::symbol::{kw, sym, Symbol};
+use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::Span;
 
 pub fn expand(
diff --git a/src/librustc_builtin_macros/global_asm.rs b/src/librustc_builtin_macros/global_asm.rs
index 307e7fe7121..2729239f62b 100644
--- a/src/librustc_builtin_macros/global_asm.rs
+++ b/src/librustc_builtin_macros/global_asm.rs
@@ -15,6 +15,7 @@ use rustc_ast::tokenstream::TokenStream;
 use rustc_errors::DiagnosticBuilder;
 use rustc_expand::base::{self, *};
 use rustc_span::source_map::respan;
+use rustc_span::symbol::Ident;
 use rustc_span::Span;
 use smallvec::smallvec;
 
@@ -25,7 +26,7 @@ pub fn expand_global_asm<'cx>(
 ) -> Box<dyn base::MacResult + 'cx> {
     match parse_global_asm(cx, sp, tts) {
         Ok(Some(global_asm)) => MacEager::items(smallvec![P(ast::Item {
-            ident: ast::Ident::invalid(),
+            ident: Ident::invalid(),
             attrs: Vec::new(),
             id: ast::DUMMY_NODE_ID,
             kind: ast::ItemKind::GlobalAsm(P(global_asm)),
diff --git a/src/librustc_builtin_macros/lib.rs b/src/librustc_builtin_macros/lib.rs
index bc1767a1238..cc77bb73c5a 100644
--- a/src/librustc_builtin_macros/lib.rs
+++ b/src/librustc_builtin_macros/lib.rs
@@ -14,11 +14,10 @@ extern crate proc_macro;
 
 use crate::deriving::*;
 
-use rustc_ast::ast::Ident;
 use rustc_expand::base::{MacroExpanderFn, Resolver, SyntaxExtension, SyntaxExtensionKind};
 use rustc_expand::proc_macro::BangProcMacro;
 use rustc_span::edition::Edition;
-use rustc_span::symbol::sym;
+use rustc_span::symbol::{sym, Ident};
 
 mod assert;
 mod cfg;
diff --git a/src/librustc_builtin_macros/proc_macro_harness.rs b/src/librustc_builtin_macros/proc_macro_harness.rs
index 735de4f0a5b..adaf5f03079 100644
--- a/src/librustc_builtin_macros/proc_macro_harness.rs
+++ b/src/librustc_builtin_macros/proc_macro_harness.rs
@@ -1,6 +1,6 @@
 use std::mem;
 
-use rustc_ast::ast::{self, Ident, NodeId};
+use rustc_ast::ast::{self, NodeId};
 use rustc_ast::attr;
 use rustc_ast::expand::is_proc_macro_attr;
 use rustc_ast::ptr::P;
@@ -11,17 +11,17 @@ use rustc_expand::expand::{AstFragment, ExpansionConfig};
 use rustc_session::parse::ParseSess;
 use rustc_span::hygiene::AstPass;
 use rustc_span::source_map::SourceMap;
-use rustc_span::symbol::{kw, sym};
+use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{Span, DUMMY_SP};
 use smallvec::smallvec;
 use std::cell::RefCell;
 
 struct ProcMacroDerive {
     id: NodeId,
-    trait_name: ast::Name,
+    trait_name: Symbol,
     function_name: Ident,
     span: Span,
-    attrs: Vec<ast::Name>,
+    attrs: Vec<Symbol>,
 }
 
 enum ProcMacroDefType {
@@ -480,7 +480,7 @@ fn mk_decls(
 
     let anon_constant = cx.item_const(
         span,
-        ast::Ident::new(kw::Underscore, span),
+        Ident::new(kw::Underscore, span),
         cx.ty(span, ast::TyKind::Tup(Vec::new())),
         block,
     );
diff --git a/src/librustc_builtin_macros/standard_library_imports.rs b/src/librustc_builtin_macros/standard_library_imports.rs
index f48fd6df9c9..cd3773c76c4 100644
--- a/src/librustc_builtin_macros/standard_library_imports.rs
+++ b/src/librustc_builtin_macros/standard_library_imports.rs
@@ -60,17 +60,17 @@ pub fn inject(
     let name = names[0];
 
     let import_path = if rust_2018 {
-        [name, sym::prelude, sym::v1].iter().map(|symbol| ast::Ident::new(*symbol, span)).collect()
+        [name, sym::prelude, sym::v1].iter().map(|symbol| Ident::new(*symbol, span)).collect()
     } else {
         [kw::PathRoot, name, sym::prelude, sym::v1]
             .iter()
-            .map(|symbol| ast::Ident::new(*symbol, span))
+            .map(|symbol| Ident::new(*symbol, span))
             .collect()
     };
 
     let use_item = cx.item(
         span,
-        ast::Ident::invalid(),
+        Ident::invalid(),
         vec![cx.attribute(cx.meta_word(span, sym::prelude_import))],
         ast::ItemKind::Use(P(ast::UseTree {
             prefix: cx.path(span, import_path),
diff --git a/src/librustc_builtin_macros/test.rs b/src/librustc_builtin_macros/test.rs
index bdc4ae2fe27..d62f34bab1a 100644
--- a/src/librustc_builtin_macros/test.rs
+++ b/src/librustc_builtin_macros/test.rs
@@ -7,7 +7,7 @@ use rustc_ast::attr;
 use rustc_ast_pretty::pprust;
 use rustc_expand::base::*;
 use rustc_span::source_map::respan;
-use rustc_span::symbol::{sym, Symbol};
+use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::Span;
 
 use std::iter;
@@ -105,7 +105,7 @@ pub fn expand_test_or_bench(
 
     let (sp, attr_sp) = (cx.with_def_site_ctxt(item.span), cx.with_def_site_ctxt(attr_sp));
 
-    let test_id = ast::Ident::new(sym::test, attr_sp);
+    let test_id = Ident::new(sym::test, attr_sp);
 
     // creates test::$name
     let test_path = |name| cx.path(sp, vec![test_id, cx.ident_of(name, sp)]);
@@ -172,12 +172,12 @@ pub fn expand_test_or_bench(
 
     let mut test_const = cx.item(
         sp,
-        ast::Ident::new(item.ident.name, sp),
+        Ident::new(item.ident.name, sp),
         vec![
             // #[cfg(test)]
             cx.attribute(attr::mk_list_item(
-                ast::Ident::new(sym::cfg, attr_sp),
-                vec![attr::mk_nested_word_item(ast::Ident::new(sym::test, attr_sp))],
+                Ident::new(sym::cfg, attr_sp),
+                vec![attr::mk_nested_word_item(Ident::new(sym::test, attr_sp))],
             )),
             // #[rustc_test_marker]
             cx.attribute(cx.meta_word(attr_sp, sym::rustc_test_marker)),
@@ -288,7 +288,7 @@ pub fn expand_test_or_bench(
     ]
 }
 
-fn item_path(mod_path: &[ast::Ident], item_ident: &ast::Ident) -> String {
+fn item_path(mod_path: &[Ident], item_ident: &Ident) -> String {
     mod_path
         .iter()
         .chain(iter::once(item_ident))
diff --git a/src/librustc_builtin_macros/test_harness.rs b/src/librustc_builtin_macros/test_harness.rs
index aca1c69dfd5..34ed4c800e0 100644
--- a/src/librustc_builtin_macros/test_harness.rs
+++ b/src/librustc_builtin_macros/test_harness.rs
@@ -1,7 +1,7 @@
 // Code that generates a test runner to run all the tests in a crate
 
 use log::debug;
-use rustc_ast::ast::{self, Ident};
+use rustc_ast::ast;
 use rustc_ast::attr;
 use rustc_ast::entry::{self, EntryPointType};
 use rustc_ast::mut_visit::{ExpectOne, *};
@@ -12,7 +12,7 @@ use rustc_feature::Features;
 use rustc_session::parse::ParseSess;
 use rustc_span::hygiene::{AstPass, SyntaxContext, Transparency};
 use rustc_span::source_map::respan;
-use rustc_span::symbol::{sym, Symbol};
+use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::{Span, DUMMY_SP};
 use rustc_target::spec::PanicStrategy;
 use smallvec::{smallvec, SmallVec};
diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs
index e261ac65446..dd9ada0b95d 100644
--- a/src/librustc_codegen_llvm/back/write.rs
+++ b/src/librustc_codegen_llvm/back/write.rs
@@ -165,6 +165,13 @@ pub fn target_machine_factory(
 
     let asm_comments = sess.asm_comments();
     let relax_elf_relocations = sess.target.target.options.relax_elf_relocations;
+
+    let use_init_array = !sess
+        .opts
+        .debugging_opts
+        .use_ctors_section
+        .unwrap_or(sess.target.target.options.use_ctors_section);
+
     Arc::new(move || {
         let tm = unsafe {
             llvm::LLVMRustCreateTargetMachine(
@@ -184,6 +191,7 @@ pub fn target_machine_factory(
                 asm_comments,
                 emit_stack_size_section,
                 relax_elf_relocations,
+                use_init_array,
             )
         };
 
diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs
index 1415fedf11a..856f989bc10 100644
--- a/src/librustc_codegen_llvm/common.rs
+++ b/src/librustc_codegen_llvm/common.rs
@@ -244,9 +244,8 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
                 }
             }
             Scalar::Ptr(ptr) => {
-                let alloc_kind = self.tcx.alloc_map.lock().get(ptr.alloc_id);
-                let base_addr = match alloc_kind {
-                    Some(GlobalAlloc::Memory(alloc)) => {
+                let base_addr = match self.tcx.global_alloc(ptr.alloc_id) {
+                    GlobalAlloc::Memory(alloc) => {
                         let init = const_alloc_to_llvm(self, alloc);
                         let value = match alloc.mutability {
                             Mutability::Mut => self.static_addr_of_mut(init, alloc.align, None),
@@ -257,12 +256,11 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
                         }
                         value
                     }
-                    Some(GlobalAlloc::Function(fn_instance)) => self.get_fn_addr(fn_instance),
-                    Some(GlobalAlloc::Static(def_id)) => {
+                    GlobalAlloc::Function(fn_instance) => self.get_fn_addr(fn_instance),
+                    GlobalAlloc::Static(def_id) => {
                         assert!(self.tcx.is_static(def_id));
                         self.get_static(def_id)
                     }
-                    None => bug!("missing allocation {:?}", ptr.alloc_id),
                 };
                 let llval = unsafe {
                     llvm::LLVMConstInBoundsGEP(
diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs
index 03bba7657bb..fb9a27ed001 100644
--- a/src/librustc_codegen_llvm/debuginfo/metadata.rs
+++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs
@@ -19,7 +19,6 @@ use crate::llvm::debuginfo::{
 use crate::value::Value;
 
 use log::debug;
-use rustc_ast::ast;
 use rustc_codegen_ssa::traits::*;
 use rustc_data_structures::const_cstr;
 use rustc_data_structures::fingerprint::Fingerprint;
@@ -93,7 +92,7 @@ pub const UNKNOWN_COLUMN_NUMBER: c_uint = 0;
 pub const NO_SCOPE_METADATA: Option<&DIScope> = None;
 
 #[derive(Copy, Debug, Hash, Eq, PartialEq, Clone)]
-pub struct UniqueTypeId(ast::Name);
+pub struct UniqueTypeId(Symbol);
 
 /// The `TypeMap` is where the `CrateDebugContext` holds the type metadata nodes
 /// created so far. The metadata nodes are indexed by `UniqueTypeId`, and, for
@@ -1300,7 +1299,7 @@ fn use_enum_fallback(cx: &CodegenCx<'_, '_>) -> bool {
 fn generator_layout_and_saved_local_names(
     tcx: TyCtxt<'tcx>,
     def_id: DefId,
-) -> (&'tcx GeneratorLayout<'tcx>, IndexVec<mir::GeneratorSavedLocal, Option<ast::Name>>) {
+) -> (&'tcx GeneratorLayout<'tcx>, IndexVec<mir::GeneratorSavedLocal, Option<Symbol>>) {
     let body = tcx.optimized_mir(def_id);
     let generator_layout = body.generator_layout.as_ref().unwrap();
     let mut generator_saved_local_names = IndexVec::from_elem(None, &generator_layout.field_tys);
@@ -1656,7 +1655,7 @@ enum VariantInfo<'a, 'tcx> {
     Generator {
         substs: SubstsRef<'tcx>,
         generator_layout: &'tcx GeneratorLayout<'tcx>,
-        generator_saved_local_names: &'a IndexVec<mir::GeneratorSavedLocal, Option<ast::Name>>,
+        generator_saved_local_names: &'a IndexVec<mir::GeneratorSavedLocal, Option<Symbol>>,
         variant_index: VariantIdx,
     },
 }
diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs
index 92e210cdd8c..8c9a2c09c27 100644
--- a/src/librustc_codegen_llvm/debuginfo/mod.rs
+++ b/src/librustc_codegen_llvm/debuginfo/mod.rs
@@ -17,7 +17,6 @@ use crate::llvm::debuginfo::{
 };
 use crate::value::Value;
 
-use rustc_ast::ast;
 use rustc_codegen_ssa::debuginfo::type_names;
 use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext, VariableKind};
 use rustc_codegen_ssa::traits::*;
@@ -529,7 +528,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
     fn create_dbg_var(
         &self,
         dbg_context: &FunctionDebugContext<&'ll DIScope>,
-        variable_name: ast::Name,
+        variable_name: Symbol,
         variable_type: Ty<'tcx>,
         scope_metadata: &'ll DIScope,
         variable_kind: VariableKind,
diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs
index 477712f5053..0d466c2cd74 100644
--- a/src/librustc_codegen_llvm/llvm/ffi.rs
+++ b/src/librustc_codegen_llvm/llvm/ffi.rs
@@ -1956,6 +1956,7 @@ extern "C" {
         AsmComments: bool,
         EmitStackSizeSection: bool,
         RelaxELFRelocations: bool,
+        UseInitArray: bool,
     ) -> Option<&'static mut TargetMachine>;
     pub fn LLVMRustDisposeTargetMachine(T: &'static mut TargetMachine);
     pub fn LLVMRustAddBuilderLibraryInfo(
diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs
index c484867a4e2..937c7457c63 100644
--- a/src/librustc_codegen_ssa/mir/operand.rs
+++ b/src/librustc_codegen_ssa/mir/operand.rs
@@ -92,7 +92,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
                     _ => bug!("from_const: invalid ScalarPair layout: {:#?}", layout),
                 };
                 let a = Scalar::from(Pointer::new(
-                    bx.tcx().alloc_map.lock().create_memory_alloc(data),
+                    bx.tcx().create_memory_alloc(data),
                     Size::from_bytes(start),
                 ));
                 let a_llval = bx.scalar_to_backend(
diff --git a/src/librustc_codegen_ssa/traits/debuginfo.rs b/src/librustc_codegen_ssa/traits/debuginfo.rs
index 34be1cfdd88..1ee0f489ffc 100644
--- a/src/librustc_codegen_ssa/traits/debuginfo.rs
+++ b/src/librustc_codegen_ssa/traits/debuginfo.rs
@@ -1,10 +1,9 @@
 use super::BackendTypes;
 use crate::mir::debuginfo::{FunctionDebugContext, VariableKind};
-use rustc_ast::ast::Name;
 use rustc_hir::def_id::CrateNum;
 use rustc_middle::mir;
 use rustc_middle::ty::{Instance, Ty};
-use rustc_span::{SourceFile, Span};
+use rustc_span::{SourceFile, Span, Symbol};
 use rustc_target::abi::call::FnAbi;
 use rustc_target::abi::Size;
 
@@ -36,7 +35,7 @@ pub trait DebugInfoMethods<'tcx>: BackendTypes {
     fn create_dbg_var(
         &self,
         dbg_context: &FunctionDebugContext<Self::DIScope>,
-        variable_name: Name,
+        variable_name: Symbol,
         variable_type: Ty<'tcx>,
         scope_metadata: Self::DIScope,
         variable_kind: VariableKind,
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index 610e9b90510..a443b8f464f 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -11,6 +11,7 @@ use rustc_middle::ty::{self, TyCtxt};
 use rustc_mir::util::{write_mir_graphviz, write_mir_pretty};
 use rustc_session::config::{Input, PpMode, PpSourceMode};
 use rustc_session::Session;
+use rustc_span::symbol::Ident;
 use rustc_span::FileName;
 
 use std::cell::Cell;
@@ -284,7 +285,7 @@ impl<'a> PrinterSupport for HygieneAnnotation<'a> {
 impl<'a> pprust::PpAnn for HygieneAnnotation<'a> {
     fn post(&self, s: &mut pprust::State<'_>, node: pprust::AnnNode<'_>) {
         match node {
-            pprust::AnnNode::Ident(&ast::Ident { name, span }) => {
+            pprust::AnnNode::Ident(&Ident { name, span }) => {
                 s.s.space();
                 s.synth_comment(format!("{}{:?}", name.as_u32(), span.ctxt()))
             }
diff --git a/src/librustc_expand/base.rs b/src/librustc_expand/base.rs
index 59c1a5468f1..fe5bf6f82c6 100644
--- a/src/librustc_expand/base.rs
+++ b/src/librustc_expand/base.rs
@@ -1,7 +1,7 @@
 use crate::expand::{self, AstFragment, Invocation};
 use crate::module::DirectoryOwnership;
 
-use rustc_ast::ast::{self, Attribute, Name, NodeId, PatKind};
+use rustc_ast::ast::{self, Attribute, NodeId, PatKind};
 use rustc_ast::mut_visit::{self, MutVisitor};
 use rustc_ast::ptr::P;
 use rustc_ast::token;
@@ -796,7 +796,7 @@ impl SyntaxExtension {
         span: Span,
         helper_attrs: Vec<Symbol>,
         edition: Edition,
-        name: Name,
+        name: Symbol,
         attrs: &[ast::Attribute],
     ) -> SyntaxExtension {
         let allow_internal_unstable = attr::allow_internal_unstable(&attrs, &sess.span_diagnostic)
@@ -885,7 +885,7 @@ pub trait Resolver {
 
     fn resolve_dollar_crates(&mut self);
     fn visit_ast_fragment_with_placeholders(&mut self, expn_id: ExpnId, fragment: &AstFragment);
-    fn register_builtin_macro(&mut self, ident: ast::Ident, ext: SyntaxExtension);
+    fn register_builtin_macro(&mut self, ident: Ident, ext: SyntaxExtension);
 
     fn expansion_for_ast_pass(
         &mut self,
@@ -913,7 +913,7 @@ pub trait Resolver {
 
 #[derive(Clone)]
 pub struct ModuleData {
-    pub mod_path: Vec<ast::Ident>,
+    pub mod_path: Vec<Ident>,
     pub directory: PathBuf,
 }
 
@@ -1052,16 +1052,16 @@ impl<'a> ExtCtxt<'a> {
     pub fn set_trace_macros(&mut self, x: bool) {
         self.ecfg.trace_mac = x
     }
-    pub fn ident_of(&self, st: &str, sp: Span) -> ast::Ident {
-        ast::Ident::from_str_and_span(st, sp)
+    pub fn ident_of(&self, st: &str, sp: Span) -> Ident {
+        Ident::from_str_and_span(st, sp)
     }
-    pub fn std_path(&self, components: &[Symbol]) -> Vec<ast::Ident> {
+    pub fn std_path(&self, components: &[Symbol]) -> Vec<Ident> {
         let def_site = self.with_def_site_ctxt(DUMMY_SP);
         iter::once(Ident::new(kw::DollarCrate, def_site))
             .chain(components.iter().map(|&s| Ident::with_dummy_span(s)))
             .collect()
     }
-    pub fn name_of(&self, st: &str) -> ast::Name {
+    pub fn name_of(&self, st: &str) -> Symbol {
         Symbol::intern(st)
     }
 
diff --git a/src/librustc_expand/build.rs b/src/librustc_expand/build.rs
index 4d89bf79e7c..be2c52a85eb 100644
--- a/src/librustc_expand/build.rs
+++ b/src/librustc_expand/build.rs
@@ -1,28 +1,28 @@
 use crate::base::ExtCtxt;
 
-use rustc_ast::ast::{self, AttrVec, BlockCheckMode, Expr, Ident, PatKind, UnOp};
+use rustc_ast::ast::{self, AttrVec, BlockCheckMode, Expr, PatKind, UnOp};
 use rustc_ast::attr;
 use rustc_ast::ptr::P;
 use rustc_span::source_map::{respan, Spanned};
-use rustc_span::symbol::{kw, sym, Symbol};
+use rustc_span::symbol::{kw, sym, Ident, Symbol};
 
 use rustc_span::Span;
 
 impl<'a> ExtCtxt<'a> {
-    pub fn path(&self, span: Span, strs: Vec<ast::Ident>) -> ast::Path {
+    pub fn path(&self, span: Span, strs: Vec<Ident>) -> ast::Path {
         self.path_all(span, false, strs, vec![])
     }
-    pub fn path_ident(&self, span: Span, id: ast::Ident) -> ast::Path {
+    pub fn path_ident(&self, span: Span, id: Ident) -> ast::Path {
         self.path(span, vec![id])
     }
-    pub fn path_global(&self, span: Span, strs: Vec<ast::Ident>) -> ast::Path {
+    pub fn path_global(&self, span: Span, strs: Vec<Ident>) -> ast::Path {
         self.path_all(span, true, strs, vec![])
     }
     pub fn path_all(
         &self,
         span: Span,
         global: bool,
-        mut idents: Vec<ast::Ident>,
+        mut idents: Vec<Ident>,
         args: Vec<ast::GenericArg>,
     ) -> ast::Path {
         assert!(!idents.is_empty());
@@ -63,7 +63,7 @@ impl<'a> ExtCtxt<'a> {
 
     // Might need to take bounds as an argument in the future, if you ever want
     // to generate a bounded existential trait type.
-    pub fn ty_ident(&self, span: Span, ident: ast::Ident) -> P<ast::Ty> {
+    pub fn ty_ident(&self, span: Span, ident: Ident) -> P<ast::Ty> {
         self.ty_path(self.path_ident(span, ident))
     }
 
@@ -74,7 +74,7 @@ impl<'a> ExtCtxt<'a> {
         }
     }
 
-    pub fn const_ident(&self, span: Span, ident: ast::Ident) -> ast::AnonConst {
+    pub fn const_ident(&self, span: Span, ident: Ident) -> ast::AnonConst {
         self.anon_const(span, ast::ExprKind::Path(None, self.path_ident(span, ident)))
     }
 
@@ -95,7 +95,7 @@ impl<'a> ExtCtxt<'a> {
     pub fn typaram(
         &self,
         span: Span,
-        ident: ast::Ident,
+        ident: Ident,
         attrs: Vec<ast::Attribute>,
         bounds: ast::GenericBounds,
         default: Option<P<ast::Ty>>,
@@ -129,14 +129,14 @@ impl<'a> ExtCtxt<'a> {
         )
     }
 
-    pub fn lifetime(&self, span: Span, ident: ast::Ident) -> ast::Lifetime {
+    pub fn lifetime(&self, span: Span, ident: Ident) -> ast::Lifetime {
         ast::Lifetime { id: ast::DUMMY_NODE_ID, ident: ident.with_span_pos(span) }
     }
 
     pub fn lifetime_def(
         &self,
         span: Span,
-        ident: ast::Ident,
+        ident: Ident,
         attrs: Vec<ast::Attribute>,
         bounds: ast::GenericBounds,
     ) -> ast::GenericParam {
@@ -155,13 +155,7 @@ impl<'a> ExtCtxt<'a> {
         ast::Stmt { id: ast::DUMMY_NODE_ID, span: expr.span, kind: ast::StmtKind::Expr(expr) }
     }
 
-    pub fn stmt_let(
-        &self,
-        sp: Span,
-        mutbl: bool,
-        ident: ast::Ident,
-        ex: P<ast::Expr>,
-    ) -> ast::Stmt {
+    pub fn stmt_let(&self, sp: Span, mutbl: bool, ident: Ident, ex: P<ast::Expr>) -> ast::Stmt {
         let pat = if mutbl {
             let binding_mode = ast::BindingMode::ByValue(ast::Mutability::Mut);
             self.pat_ident_binding_mode(sp, ident, binding_mode)
@@ -218,7 +212,7 @@ impl<'a> ExtCtxt<'a> {
         self.expr(path.span, ast::ExprKind::Path(None, path))
     }
 
-    pub fn expr_ident(&self, span: Span, id: ast::Ident) -> P<ast::Expr> {
+    pub fn expr_ident(&self, span: Span, id: Ident) -> P<ast::Expr> {
         self.expr_path(self.path_ident(span, id))
     }
     pub fn expr_self(&self, span: Span) -> P<ast::Expr> {
@@ -251,18 +245,13 @@ impl<'a> ExtCtxt<'a> {
     ) -> P<ast::Expr> {
         self.expr(span, ast::ExprKind::Call(expr, args))
     }
-    pub fn expr_call_ident(
-        &self,
-        span: Span,
-        id: ast::Ident,
-        args: Vec<P<ast::Expr>>,
-    ) -> P<ast::Expr> {
+    pub fn expr_call_ident(&self, span: Span, id: Ident, args: Vec<P<ast::Expr>>) -> P<ast::Expr> {
         self.expr(span, ast::ExprKind::Call(self.expr_ident(span, id), args))
     }
     pub fn expr_call_global(
         &self,
         sp: Span,
-        fn_path: Vec<ast::Ident>,
+        fn_path: Vec<Ident>,
         args: Vec<P<ast::Expr>>,
     ) -> P<ast::Expr> {
         let pathexpr = self.expr_path(self.path_global(sp, fn_path));
@@ -272,7 +261,7 @@ impl<'a> ExtCtxt<'a> {
         &self,
         span: Span,
         expr: P<ast::Expr>,
-        ident: ast::Ident,
+        ident: Ident,
         mut args: Vec<P<ast::Expr>>,
     ) -> P<ast::Expr> {
         args.insert(0, expr);
@@ -304,7 +293,7 @@ impl<'a> ExtCtxt<'a> {
     pub fn expr_struct_ident(
         &self,
         span: Span,
-        id: ast::Ident,
+        id: Ident,
         fields: Vec<ast::Field>,
     ) -> P<ast::Expr> {
         self.expr_struct(span, self.path_ident(span, id), fields)
@@ -405,7 +394,7 @@ impl<'a> ExtCtxt<'a> {
     pub fn pat_lit(&self, span: Span, expr: P<ast::Expr>) -> P<ast::Pat> {
         self.pat(span, PatKind::Lit(expr))
     }
-    pub fn pat_ident(&self, span: Span, ident: ast::Ident) -> P<ast::Pat> {
+    pub fn pat_ident(&self, span: Span, ident: Ident) -> P<ast::Pat> {
         let binding_mode = ast::BindingMode::ByValue(ast::Mutability::Not);
         self.pat_ident_binding_mode(span, ident, binding_mode)
     }
@@ -413,7 +402,7 @@ impl<'a> ExtCtxt<'a> {
     pub fn pat_ident_binding_mode(
         &self,
         span: Span,
-        ident: ast::Ident,
+        ident: Ident,
         bm: ast::BindingMode,
     ) -> P<ast::Pat> {
         let pat = PatKind::Ident(bm, ident.with_span_pos(span), None);
@@ -517,7 +506,7 @@ impl<'a> ExtCtxt<'a> {
         )
     }
 
-    pub fn lambda(&self, span: Span, ids: Vec<ast::Ident>, body: P<ast::Expr>) -> P<ast::Expr> {
+    pub fn lambda(&self, span: Span, ids: Vec<Ident>, body: P<ast::Expr>) -> P<ast::Expr> {
         let fn_decl = self.fn_decl(
             ids.iter().map(|id| self.param(span, *id, self.ty(span, ast::TyKind::Infer))).collect(),
             ast::FnRetTy::Default(span),
@@ -544,20 +533,15 @@ impl<'a> ExtCtxt<'a> {
         self.lambda(span, Vec::new(), body)
     }
 
-    pub fn lambda1(&self, span: Span, body: P<ast::Expr>, ident: ast::Ident) -> P<ast::Expr> {
+    pub fn lambda1(&self, span: Span, body: P<ast::Expr>, ident: Ident) -> P<ast::Expr> {
         self.lambda(span, vec![ident], body)
     }
 
-    pub fn lambda_stmts_1(
-        &self,
-        span: Span,
-        stmts: Vec<ast::Stmt>,
-        ident: ast::Ident,
-    ) -> P<ast::Expr> {
+    pub fn lambda_stmts_1(&self, span: Span, stmts: Vec<ast::Stmt>, ident: Ident) -> P<ast::Expr> {
         self.lambda1(span, self.expr_block(self.block(span, stmts)), ident)
     }
 
-    pub fn param(&self, span: Span, ident: ast::Ident, ty: P<ast::Ty>) -> ast::Param {
+    pub fn param(&self, span: Span, ident: Ident, ty: P<ast::Ty>) -> ast::Param {
         let arg_pat = self.pat_ident(span, ident);
         ast::Param {
             attrs: AttrVec::default(),
@@ -653,7 +637,7 @@ impl<'a> ExtCtxt<'a> {
         attr::mk_attr_outer(mi)
     }
 
-    pub fn meta_word(&self, sp: Span, w: ast::Name) -> ast::MetaItem {
+    pub fn meta_word(&self, sp: Span, w: Symbol) -> ast::MetaItem {
         attr::mk_word_item(Ident::new(w, sp))
     }
 }
diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs
index 972e75d201b..427d04d3a97 100644
--- a/src/librustc_expand/expand.rs
+++ b/src/librustc_expand/expand.rs
@@ -7,7 +7,7 @@ use crate::module::{parse_external_mod, push_directory, Directory, DirectoryOwne
 use crate::placeholders::{placeholder, PlaceholderExpander};
 use crate::proc_macro::collect_derives;
 
-use rustc_ast::ast::{self, AttrItem, Block, Ident, LitKind, NodeId, PatKind, Path};
+use rustc_ast::ast::{self, AttrItem, Block, LitKind, NodeId, PatKind, Path};
 use rustc_ast::ast::{ItemKind, MacArgs, MacStmtStyle, StmtKind};
 use rustc_ast::mut_visit::*;
 use rustc_ast::ptr::P;
@@ -25,7 +25,7 @@ use rustc_session::lint::builtin::UNUSED_DOC_COMMENTS;
 use rustc_session::lint::BuiltinLintDiagnostics;
 use rustc_session::parse::{feature_err, ParseSess};
 use rustc_span::source_map::respan;
-use rustc_span::symbol::{sym, Symbol};
+use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::{FileName, Span, DUMMY_SP};
 
 use smallvec::{smallvec, SmallVec};
diff --git a/src/librustc_expand/mbe.rs b/src/librustc_expand/mbe.rs
index 57957a1fa8b..a728261d711 100644
--- a/src/librustc_expand/mbe.rs
+++ b/src/librustc_expand/mbe.rs
@@ -9,10 +9,10 @@ crate mod macro_rules;
 crate mod quoted;
 crate mod transcribe;
 
-use rustc_ast::ast;
 use rustc_ast::token::{self, Token, TokenKind};
 use rustc_ast::tokenstream::DelimSpan;
 
+use rustc_span::symbol::Ident;
 use rustc_span::Span;
 
 use rustc_data_structures::sync::Lrc;
@@ -82,13 +82,9 @@ enum TokenTree {
     /// A kleene-style repetition sequence
     Sequence(DelimSpan, Lrc<SequenceRepetition>),
     /// e.g., `$var`
-    MetaVar(Span, ast::Ident),
+    MetaVar(Span, Ident),
     /// e.g., `$var:expr`. This is only used in the left hand side of MBE macros.
-    MetaVarDecl(
-        Span,
-        ast::Ident, /* name to bind */
-        ast::Ident, /* kind of nonterminal */
-    ),
+    MetaVarDecl(Span, Ident /* name to bind */, Ident /* kind of nonterminal */),
 }
 
 impl TokenTree {
diff --git a/src/librustc_expand/mbe/macro_parser.rs b/src/librustc_expand/mbe/macro_parser.rs
index 350473ab9ae..0cf092d912b 100644
--- a/src/librustc_expand/mbe/macro_parser.rs
+++ b/src/librustc_expand/mbe/macro_parser.rs
@@ -76,7 +76,6 @@ use TokenTreeOrTokenTreeSlice::*;
 
 use crate::mbe::{self, TokenTree};
 
-use rustc_ast::ast::Name;
 use rustc_ast::ptr::P;
 use rustc_ast::token::{self, DocComment, Nonterminal, Token};
 use rustc_ast_pretty::pprust;
@@ -766,7 +765,7 @@ fn get_macro_ident(token: &Token) -> Option<(Ident, bool)> {
 ///
 /// Returning `false` is a *stability guarantee* that such a matcher will *never* begin with that
 /// token. Be conservative (return true) if not sure.
-fn may_begin_with(token: &Token, name: Name) -> bool {
+fn may_begin_with(token: &Token, name: Symbol) -> bool {
     /// Checks whether the non-terminal may contain a single (non-keyword) identifier.
     fn may_be_ident(nt: &token::Nonterminal) -> bool {
         match *nt {
diff --git a/src/librustc_expand/mbe/macro_rules.rs b/src/librustc_expand/mbe/macro_rules.rs
index 7d2c4fbf7af..ecadf320f87 100644
--- a/src/librustc_expand/mbe/macro_rules.rs
+++ b/src/librustc_expand/mbe/macro_rules.rs
@@ -21,7 +21,7 @@ use rustc_parse::parser::Parser;
 use rustc_session::parse::ParseSess;
 use rustc_span::edition::Edition;
 use rustc_span::hygiene::Transparency;
-use rustc_span::symbol::{kw, sym, MacroRulesNormalizedIdent, Symbol};
+use rustc_span::symbol::{kw, sym, Ident, MacroRulesNormalizedIdent, Symbol};
 use rustc_span::Span;
 
 use log::debug;
@@ -39,7 +39,7 @@ crate struct ParserAnyMacro<'a> {
     /// Span of the expansion site of the macro this parser is for
     site_span: Span,
     /// The ident of the macro we're parsing
-    macro_ident: ast::Ident,
+    macro_ident: Ident,
     arm_span: Span,
 }
 
@@ -88,7 +88,7 @@ fn emit_frag_parse_err(
     parser: &Parser<'_>,
     orig_parser: &mut Parser<'_>,
     site_span: Span,
-    macro_ident: ast::Ident,
+    macro_ident: Ident,
     arm_span: Span,
     kind: AstFragmentKind,
 ) {
@@ -166,7 +166,7 @@ impl<'a> ParserAnyMacro<'a> {
 }
 
 struct MacroRulesMacroExpander {
-    name: ast::Ident,
+    name: Ident,
     span: Span,
     transparency: Transparency,
     lhses: Vec<mbe::TokenTree>,
@@ -215,7 +215,7 @@ fn generic_extension<'cx>(
     cx: &'cx mut ExtCtxt<'_>,
     sp: Span,
     def_span: Span,
-    name: ast::Ident,
+    name: Ident,
     transparency: Transparency,
     arg: TokenStream,
     lhses: &[mbe::TokenTree],
@@ -400,9 +400,9 @@ pub fn compile_declarative_macro(
     };
 
     let diag = &sess.span_diagnostic;
-    let lhs_nm = ast::Ident::new(sym::lhs, def.span);
-    let rhs_nm = ast::Ident::new(sym::rhs, def.span);
-    let tt_spec = ast::Ident::new(sym::tt, def.span);
+    let lhs_nm = Ident::new(sym::lhs, def.span);
+    let rhs_nm = Ident::new(sym::rhs, def.span);
+    let tt_spec = Ident::new(sym::tt, def.span);
 
     // Parse the macro_rules! invocation
     let (macro_rules, body) = match &def.kind {
diff --git a/src/librustc_expand/mbe/quoted.rs b/src/librustc_expand/mbe/quoted.rs
index b19fae65597..3295f5b392d 100644
--- a/src/librustc_expand/mbe/quoted.rs
+++ b/src/librustc_expand/mbe/quoted.rs
@@ -1,12 +1,11 @@
 use crate::mbe::macro_parser;
 use crate::mbe::{Delimited, KleeneOp, KleeneToken, SequenceRepetition, TokenTree};
 
-use rustc_ast::ast;
 use rustc_ast::token::{self, Token};
 use rustc_ast::tokenstream;
 use rustc_ast_pretty::pprust;
 use rustc_session::parse::ParseSess;
-use rustc_span::symbol::kw;
+use rustc_span::symbol::{kw, Ident};
 
 use rustc_span::Span;
 
@@ -67,7 +66,7 @@ pub(super) fn parse(
                     tree => tree.as_ref().map(tokenstream::TokenTree::span).unwrap_or(start_sp),
                 };
                 sess.missing_fragment_specifiers.borrow_mut().insert(span);
-                result.push(TokenTree::MetaVarDecl(span, ident, ast::Ident::invalid()));
+                result.push(TokenTree::MetaVarDecl(span, ident, Ident::invalid()));
             }
 
             // Not a metavar or no matchers allowed, so just return the tree
@@ -145,7 +144,7 @@ fn parse_tree(
                 let msg =
                     format!("expected identifier, found `{}`", pprust::token_to_string(&token),);
                 sess.span_diagnostic.span_err(token.span, &msg);
-                TokenTree::MetaVar(token.span, ast::Ident::invalid())
+                TokenTree::MetaVar(token.span, Ident::invalid())
             }
 
             // There are no more tokens. Just return the `$` we already have.
diff --git a/src/librustc_expand/module.rs b/src/librustc_expand/module.rs
index aad92a09743..9bb2b57b7f5 100644
--- a/src/librustc_expand/module.rs
+++ b/src/librustc_expand/module.rs
@@ -1,10 +1,10 @@
-use rustc_ast::ast::{self, Attribute, Ident, Mod};
+use rustc_ast::ast::{Attribute, Mod};
 use rustc_ast::{attr, token};
 use rustc_errors::{struct_span_err, PResult};
 use rustc_parse::new_parser_from_file;
 use rustc_session::parse::ParseSess;
 use rustc_span::source_map::{FileName, Span};
-use rustc_span::symbol::sym;
+use rustc_span::symbol::{sym, Ident};
 
 use std::path::{self, Path, PathBuf};
 
@@ -18,7 +18,7 @@ pub struct Directory {
 pub enum DirectoryOwnership {
     Owned {
         // None if `mod.rs`, `Some("foo")` if we're in `foo.rs`.
-        relative: Option<ast::Ident>,
+        relative: Option<Ident>,
     },
     UnownedViaBlock,
     UnownedViaMod,
@@ -40,7 +40,7 @@ pub struct ModulePathSuccess {
 
 crate fn parse_external_mod(
     sess: &ParseSess,
-    id: ast::Ident,
+    id: Ident,
     span: Span, // The span to blame on errors.
     Directory { mut ownership, path }: Directory,
     attrs: &mut Vec<Attribute>,
@@ -125,7 +125,7 @@ crate fn push_directory(
 
 fn submod_path<'a>(
     sess: &'a ParseSess,
-    id: ast::Ident,
+    id: Ident,
     span: Span,
     attrs: &[Attribute],
     ownership: DirectoryOwnership,
@@ -236,9 +236,9 @@ pub fn submod_path_from_attr(attrs: &[Attribute], dir_path: &Path) -> Option<Pat
 // Public for rustfmt usage.
 pub fn default_submod_path<'a>(
     sess: &'a ParseSess,
-    id: ast::Ident,
+    id: Ident,
     span: Span,
-    relative: Option<ast::Ident>,
+    relative: Option<Ident>,
     dir_path: &Path,
 ) -> ModulePath<'a> {
     // If we're in a foo.rs file instead of a mod.rs file,
diff --git a/src/librustc_expand/mut_visit/tests.rs b/src/librustc_expand/mut_visit/tests.rs
index 70fb8975d4d..48da1a3ccc4 100644
--- a/src/librustc_expand/mut_visit/tests.rs
+++ b/src/librustc_expand/mut_visit/tests.rs
@@ -1,9 +1,10 @@
 use crate::tests::{matches_codepattern, string_to_crate};
 
-use rustc_ast::ast::{self, Ident};
+use rustc_ast::ast;
 use rustc_ast::mut_visit::{self, MutVisitor};
 use rustc_ast::with_default_globals;
 use rustc_ast_pretty::pprust;
+use rustc_span::symbol::Ident;
 
 // This version doesn't care about getting comments or doc-strings in.
 fn fake_print_crate(s: &mut pprust::State<'_>, krate: &ast::Crate) {
@@ -14,7 +15,7 @@ fn fake_print_crate(s: &mut pprust::State<'_>, krate: &ast::Crate) {
 struct ToZzIdentMutVisitor;
 
 impl MutVisitor for ToZzIdentMutVisitor {
-    fn visit_ident(&mut self, ident: &mut ast::Ident) {
+    fn visit_ident(&mut self, ident: &mut Ident) {
         *ident = Ident::from_str("zz");
     }
     fn visit_mac(&mut self, mac: &mut ast::MacCall) {
diff --git a/src/librustc_expand/parse/tests.rs b/src/librustc_expand/parse/tests.rs
index 4add896258f..437f6e62d7d 100644
--- a/src/librustc_expand/parse/tests.rs
+++ b/src/librustc_expand/parse/tests.rs
@@ -1,6 +1,6 @@
 use crate::tests::{matches_codepattern, string_to_stream, with_error_checking_parse};
 
-use rustc_ast::ast::{self, Name, PatKind};
+use rustc_ast::ast::{self, PatKind};
 use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Token};
 use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
@@ -100,12 +100,12 @@ fn string_to_tts_1() {
 
         let expected = TokenStream::new(vec![
             TokenTree::token(token::Ident(kw::Fn, false), sp(0, 2)).into(),
-            TokenTree::token(token::Ident(Name::intern("a"), false), sp(3, 4)).into(),
+            TokenTree::token(token::Ident(Symbol::intern("a"), false), sp(3, 4)).into(),
             TokenTree::Delimited(
                 DelimSpan::from_pair(sp(5, 6), sp(13, 14)),
                 token::DelimToken::Paren,
                 TokenStream::new(vec![
-                    TokenTree::token(token::Ident(Name::intern("b"), false), sp(6, 7)).into(),
+                    TokenTree::token(token::Ident(Symbol::intern("b"), false), sp(6, 7)).into(),
                     TokenTree::token(token::Colon, sp(8, 9)).into(),
                     TokenTree::token(token::Ident(sym::i32, false), sp(10, 13)).into(),
                 ])
@@ -116,7 +116,7 @@ fn string_to_tts_1() {
                 DelimSpan::from_pair(sp(15, 16), sp(20, 21)),
                 token::DelimToken::Brace,
                 TokenStream::new(vec![
-                    TokenTree::token(token::Ident(Name::intern("b"), false), sp(17, 18)).into(),
+                    TokenTree::token(token::Ident(Symbol::intern("b"), false), sp(17, 18)).into(),
                     TokenTree::token(token::Semi, sp(18, 19)).into(),
                 ])
                 .into(),
diff --git a/src/librustc_expand/placeholders.rs b/src/librustc_expand/placeholders.rs
index e1781f8636e..23f7a5b28fe 100644
--- a/src/librustc_expand/placeholders.rs
+++ b/src/librustc_expand/placeholders.rs
@@ -5,6 +5,7 @@ use rustc_ast::ast;
 use rustc_ast::mut_visit::*;
 use rustc_ast::ptr::P;
 use rustc_span::source_map::{dummy_spanned, DUMMY_SP};
+use rustc_span::symbol::Ident;
 
 use smallvec::{smallvec, SmallVec};
 
@@ -23,7 +24,7 @@ pub fn placeholder(
         }
     }
 
-    let ident = ast::Ident::invalid();
+    let ident = Ident::invalid();
     let attrs = Vec::new();
     let vis = vis.unwrap_or_else(|| dummy_spanned(ast::VisibilityKind::Inherited));
     let span = DUMMY_SP;
diff --git a/src/librustc_expand/proc_macro_server.rs b/src/librustc_expand/proc_macro_server.rs
index 10baffb28ac..afc6dc36eb4 100644
--- a/src/librustc_expand/proc_macro_server.rs
+++ b/src/librustc_expand/proc_macro_server.rs
@@ -10,7 +10,7 @@ use rustc_errors::Diagnostic;
 use rustc_parse::lexer::nfc_normalize;
 use rustc_parse::{nt_to_tokenstream, parse_stream_from_source_str};
 use rustc_session::parse::ParseSess;
-use rustc_span::symbol::{kw, sym, Symbol};
+use rustc_span::symbol::{self, kw, sym, Symbol};
 use rustc_span::{BytePos, FileName, MultiSpan, Pos, SourceFile, Span};
 
 use pm::bridge::{server, TokenTree};
@@ -143,7 +143,7 @@ impl FromInternal<(TreeAndJoint, &'_ ParseSess, &'_ mut Vec<Self>)>
             Ident(name, false) if name == kw::DollarCrate => tt!(Ident::dollar_crate()),
             Ident(name, is_raw) => tt!(Ident::new(sess, name, is_raw)),
             Lifetime(name) => {
-                let ident = ast::Ident::new(name, span).without_first_quote();
+                let ident = symbol::Ident::new(name, span).without_first_quote();
                 stack.push(tt!(Ident::new(sess, ident.name, false)));
                 tt!(Punct::new('\'', true))
             }
diff --git a/src/librustc_expand/tokenstream/tests.rs b/src/librustc_expand/tokenstream/tests.rs
index db329f22d14..caaa08df499 100644
--- a/src/librustc_expand/tokenstream/tests.rs
+++ b/src/librustc_expand/tokenstream/tests.rs
@@ -1,10 +1,9 @@
 use crate::tests::string_to_stream;
 
-use rustc_ast::ast::Name;
 use rustc_ast::token;
 use rustc_ast::tokenstream::{TokenStream, TokenStreamBuilder, TokenTree};
 use rustc_ast::with_default_globals;
-use rustc_span::{BytePos, Span};
+use rustc_span::{BytePos, Span, Symbol};
 use smallvec::smallvec;
 
 fn string_to_ts(string: &str) -> TokenStream {
@@ -87,7 +86,7 @@ fn test_is_empty() {
     with_default_globals(|| {
         let test0: TokenStream = Vec::<TokenTree>::new().into_iter().collect();
         let test1: TokenStream =
-            TokenTree::token(token::Ident(Name::intern("a"), false), sp(0, 1)).into();
+            TokenTree::token(token::Ident(Symbol::intern("a"), false), sp(0, 1)).into();
         let test2 = string_to_ts("foo(bar::baz)");
 
         assert_eq!(test0.is_empty(), true);
diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs
index 75a5c198ec7..eafff6705ba 100644
--- a/src/librustc_hir/hir.rs
+++ b/src/librustc_hir/hir.rs
@@ -3,7 +3,7 @@ use crate::def_id::DefId;
 crate use crate::hir_id::HirId;
 use crate::itemlikevisit;
 
-use rustc_ast::ast::{self, CrateSugar, Ident, LlvmAsmDialect, Name};
+use rustc_ast::ast::{self, CrateSugar, LlvmAsmDialect};
 use rustc_ast::ast::{AttrVec, Attribute, FloatTy, IntTy, Label, LitKind, StrStyle, UintTy};
 pub use rustc_ast::ast::{BorrowKind, ImplPolarity, IsAuto};
 pub use rustc_ast::ast::{CaptureBy, Movability, Mutability};
@@ -13,7 +13,7 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::sync::{par_for_each_in, Send, Sync};
 use rustc_macros::HashStable_Generic;
 use rustc_span::source_map::{SourceMap, Spanned};
-use rustc_span::symbol::{kw, sym, Symbol};
+use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{MultiSpan, Span, DUMMY_SP};
 use rustc_target::spec::abi::Abi;
 
@@ -2443,7 +2443,7 @@ pub enum ItemKind<'hir> {
     /// An `extern crate` item, with optional *original* crate name if the crate was renamed.
     ///
     /// E.g., `extern crate foo` or `extern crate foo_bar as foo`.
-    ExternCrate(Option<Name>),
+    ExternCrate(Option<Symbol>),
 
     /// `use foo::bar::*;` or `use foo::bar::baz as quux;`
     ///
@@ -2611,7 +2611,7 @@ pub type TraitMap<ID = HirId> = NodeMap<Vec<TraitCandidate<ID>>>;
 
 // Map from the NodeId of a glob import to a list of items which are actually
 // imported.
-pub type GlobMap = NodeMap<FxHashSet<Name>>;
+pub type GlobMap = NodeMap<FxHashSet<Symbol>>;
 
 #[derive(Copy, Clone, Debug, HashStable_Generic)]
 pub enum Node<'hir> {
diff --git a/src/librustc_hir/intravisit.rs b/src/librustc_hir/intravisit.rs
index c8f3edcbda0..0270d0de5c7 100644
--- a/src/librustc_hir/intravisit.rs
+++ b/src/librustc_hir/intravisit.rs
@@ -34,8 +34,9 @@
 use crate::hir::*;
 use crate::hir_id::CRATE_HIR_ID;
 use crate::itemlikevisit::{ItemLikeVisitor, ParItemLikeVisitor};
-use rustc_ast::ast::{Attribute, Ident, Label, Name};
+use rustc_ast::ast::{Attribute, Label};
 use rustc_ast::walk_list;
+use rustc_span::symbol::{Ident, Symbol};
 use rustc_span::Span;
 
 pub struct DeepVisitor<'v, V> {
@@ -317,7 +318,7 @@ pub trait Visitor<'v>: Sized {
     fn visit_id(&mut self, _hir_id: HirId) {
         // Nothing to do.
     }
-    fn visit_name(&mut self, _span: Span, _name: Name) {
+    fn visit_name(&mut self, _span: Span, _name: Symbol) {
         // Nothing to do.
     }
     fn visit_ident(&mut self, ident: Ident) {
@@ -395,7 +396,7 @@ pub trait Visitor<'v>: Sized {
     fn visit_variant_data(
         &mut self,
         s: &'v VariantData<'v>,
-        _: Name,
+        _: Symbol,
         _: &'v Generics<'v>,
         _parent_id: HirId,
         _: Span,
diff --git a/src/librustc_hir/pat_util.rs b/src/librustc_hir/pat_util.rs
index f19b7fb69c7..2f1b5da8e13 100644
--- a/src/librustc_hir/pat_util.rs
+++ b/src/librustc_hir/pat_util.rs
@@ -1,7 +1,7 @@
 use crate::def::{CtorOf, DefKind, Res};
 use crate::def_id::DefId;
 use crate::hir::{self, HirId, PatKind};
-use rustc_ast::ast;
+use rustc_span::symbol::Ident;
 use rustc_span::Span;
 
 use std::iter::{Enumerate, ExactSizeIterator};
@@ -79,7 +79,7 @@ impl hir::Pat<'_> {
 
     /// Call `f` on every "binding" in a pattern, e.g., on `a` in
     /// `match foo() { Some(a) => (), None => () }`
-    pub fn each_binding(&self, mut f: impl FnMut(hir::BindingAnnotation, HirId, Span, ast::Ident)) {
+    pub fn each_binding(&self, mut f: impl FnMut(hir::BindingAnnotation, HirId, Span, Ident)) {
         self.walk_always(|p| {
             if let PatKind::Binding(binding_mode, _, ident, _) = p.kind {
                 f(binding_mode, p.hir_id, p.span, ident);
@@ -93,7 +93,7 @@ impl hir::Pat<'_> {
     /// When encountering an or-pattern `p_0 | ... | p_n` only `p_0` will be visited.
     pub fn each_binding_or_first(
         &self,
-        f: &mut impl FnMut(hir::BindingAnnotation, HirId, Span, ast::Ident),
+        f: &mut impl FnMut(hir::BindingAnnotation, HirId, Span, Ident),
     ) {
         self.walk(|p| match &p.kind {
             PatKind::Or(ps) => {
@@ -140,7 +140,7 @@ impl hir::Pat<'_> {
         satisfies
     }
 
-    pub fn simple_ident(&self) -> Option<ast::Ident> {
+    pub fn simple_ident(&self) -> Option<Ident> {
         match self.kind {
             PatKind::Binding(
                 hir::BindingAnnotation::Unannotated | hir::BindingAnnotation::Mutable,
diff --git a/src/librustc_hir_pretty/lib.rs b/src/librustc_hir_pretty/lib.rs
index dee51355b74..f8a42376d14 100644
--- a/src/librustc_hir_pretty/lib.rs
+++ b/src/librustc_hir_pretty/lib.rs
@@ -10,7 +10,7 @@ use rustc_hir as hir;
 use rustc_hir::{GenericArg, GenericParam, GenericParamKind, Node};
 use rustc_hir::{GenericBound, PatKind, RangeEnd, TraitBoundModifier};
 use rustc_span::source_map::{SourceMap, Spanned};
-use rustc_span::symbol::{kw, IdentPrinter};
+use rustc_span::symbol::{kw, Ident, IdentPrinter, Symbol};
 use rustc_span::{self, BytePos, FileName};
 use rustc_target::spec::abi::Abi;
 
@@ -23,7 +23,7 @@ pub fn id_to_string(map: &dyn rustc_hir::intravisit::Map<'_>, hir_id: hir::HirId
 }
 
 pub enum AnnNode<'a> {
-    Name(&'a ast::Name),
+    Name(&'a Symbol),
     Block(&'a hir::Block<'a>),
     Item(&'a hir::Item<'a>),
     SubItem(hir::HirId),
@@ -145,7 +145,7 @@ impl<'a> PrintState<'a> for State<'a> {
         &mut self.comments
     }
 
-    fn print_ident(&mut self, ident: ast::Ident) {
+    fn print_ident(&mut self, ident: Ident) {
         self.s.word(IdentPrinter::for_ast_ident(ident, ident.is_raw_guess()).to_string());
         self.ann.post(self, AnnNode::Name(&ident.name))
     }
@@ -453,7 +453,7 @@ impl<'a> State<'a> {
 
     fn print_associated_const(
         &mut self,
-        ident: ast::Ident,
+        ident: Ident,
         ty: &hir::Ty<'_>,
         default: Option<hir::BodyId>,
         vis: &hir::Visibility<'_>,
@@ -473,7 +473,7 @@ impl<'a> State<'a> {
 
     fn print_associated_type(
         &mut self,
-        ident: ast::Ident,
+        ident: Ident,
         generics: &hir::Generics<'_>,
         bounds: Option<hir::GenericBounds<'_>>,
         ty: Option<&hir::Ty<'_>>,
@@ -768,7 +768,7 @@ impl<'a> State<'a> {
         &mut self,
         enum_definition: &hir::EnumDef<'_>,
         generics: &hir::Generics<'_>,
-        name: ast::Name,
+        name: Symbol,
         span: rustc_span::Span,
         visibility: &hir::Visibility<'_>,
     ) {
@@ -827,7 +827,7 @@ impl<'a> State<'a> {
         &mut self,
         struct_def: &hir::VariantData<'_>,
         generics: &hir::Generics<'_>,
-        name: ast::Name,
+        name: Symbol,
         span: rustc_span::Span,
         print_finalizer: bool,
     ) {
@@ -886,11 +886,11 @@ impl<'a> State<'a> {
     }
     pub fn print_method_sig(
         &mut self,
-        ident: ast::Ident,
+        ident: Ident,
         m: &hir::FnSig<'_>,
         generics: &hir::Generics<'_>,
         vis: &hir::Visibility<'_>,
-        arg_names: &[ast::Ident],
+        arg_names: &[Ident],
         body_id: Option<hir::BodyId>,
     ) {
         self.print_fn(&m.decl, m.header, Some(ident.name), generics, vis, arg_names, body_id)
@@ -1297,7 +1297,7 @@ impl<'a> State<'a> {
                 self.bopen();
 
                 // Print `let _t = $init;`:
-                let temp = ast::Ident::from_str("_t");
+                let temp = Ident::from_str("_t");
                 self.print_local(Some(init), |this| this.print_ident(temp));
                 self.s.word(";");
 
@@ -1496,8 +1496,8 @@ impl<'a> State<'a> {
         self.s.word(i.to_string())
     }
 
-    pub fn print_name(&mut self, name: ast::Name) {
-        self.print_ident(ast::Ident::with_dummy_span(name))
+    pub fn print_name(&mut self, name: Symbol) {
+        self.print_ident(Ident::with_dummy_span(name))
     }
 
     pub fn print_for_decl(&mut self, loc: &hir::Local<'_>, coll: &hir::Expr<'_>) {
@@ -1888,10 +1888,10 @@ impl<'a> State<'a> {
         &mut self,
         decl: &hir::FnDecl<'_>,
         header: hir::FnHeader,
-        name: Option<ast::Name>,
+        name: Option<Symbol>,
         generics: &hir::Generics<'_>,
         vis: &hir::Visibility<'_>,
-        arg_names: &[ast::Ident],
+        arg_names: &[Ident],
         body_id: Option<hir::BodyId>,
     ) {
         self.print_fn_header_info(header, vis);
@@ -2154,9 +2154,9 @@ impl<'a> State<'a> {
         abi: Abi,
         unsafety: hir::Unsafety,
         decl: &hir::FnDecl<'_>,
-        name: Option<ast::Name>,
+        name: Option<Symbol>,
         generic_params: &[hir::GenericParam<'_>],
-        arg_names: &[ast::Ident],
+        arg_names: &[Ident],
     ) {
         self.ibox(INDENT_UNIT);
         if !generic_params.is_empty() {
diff --git a/src/librustc_incremental/assert_dep_graph.rs b/src/librustc_incremental/assert_dep_graph.rs
index 673d6e92b7e..807ae586348 100644
--- a/src/librustc_incremental/assert_dep_graph.rs
+++ b/src/librustc_incremental/assert_dep_graph.rs
@@ -44,7 +44,7 @@ use rustc_middle::dep_graph::debug::{DepNodeFilter, EdgeFilter};
 use rustc_middle::dep_graph::{DepGraphQuery, DepKind, DepNode, DepNodeExt};
 use rustc_middle::hir::map::Map;
 use rustc_middle::ty::TyCtxt;
-use rustc_span::symbol::sym;
+use rustc_span::symbol::{sym, Symbol};
 use rustc_span::Span;
 
 use std::env;
@@ -89,7 +89,7 @@ pub fn assert_dep_graph(tcx: TyCtxt<'_>) {
 }
 
 type Sources = Vec<(Span, DefId, DepNode)>;
-type Targets = Vec<(Span, ast::Name, hir::HirId, DepNode)>;
+type Targets = Vec<(Span, Symbol, hir::HirId, DepNode)>;
 
 struct IfThisChanged<'tcx> {
     tcx: TyCtxt<'tcx>,
@@ -98,7 +98,7 @@ struct IfThisChanged<'tcx> {
 }
 
 impl IfThisChanged<'tcx> {
-    fn argument(&self, attr: &ast::Attribute) -> Option<ast::Name> {
+    fn argument(&self, attr: &ast::Attribute) -> Option<Symbol> {
         let mut value = None;
         for list_item in attr.meta_item_list().unwrap_or_default() {
             match list_item.ident() {
diff --git a/src/librustc_incremental/assert_module_sources.rs b/src/librustc_incremental/assert_module_sources.rs
index 856edb3725a..eee6e73ed10 100644
--- a/src/librustc_incremental/assert_module_sources.rs
+++ b/src/librustc_incremental/assert_module_sources.rs
@@ -147,7 +147,7 @@ impl AssertModuleSource<'tcx> {
         );
     }
 
-    fn field(&self, attr: &ast::Attribute, name: Symbol) -> ast::Name {
+    fn field(&self, attr: &ast::Attribute, name: Symbol) -> Symbol {
         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 27aebf7b1b9..9bf992537df 100644
--- a/src/librustc_incremental/persist/dirty_clean.rs
+++ b/src/librustc_incremental/persist/dirty_clean.rs
@@ -499,7 +499,7 @@ fn check_config(tcx: TyCtxt<'_>, attr: &Attribute) -> bool {
     }
 }
 
-fn expect_associated_value(tcx: TyCtxt<'_>, item: &NestedMetaItem) -> ast::Name {
+fn expect_associated_value(tcx: TyCtxt<'_>, item: &NestedMetaItem) -> Symbol {
     if let Some(value) = item.value_str() {
         value
     } else {
diff --git a/src/librustc_infer/infer/canonical/canonicalizer.rs b/src/librustc_infer/infer/canonical/canonicalizer.rs
index 42ceae617ba..a0b5dd45a0e 100644
--- a/src/librustc_infer/infer/canonical/canonicalizer.rs
+++ b/src/librustc_infer/infer/canonical/canonicalizer.rs
@@ -353,8 +353,10 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
                     // `TyVar(vid)` is unresolved, track its universe index in the canonicalized
                     // result.
                     Err(mut ui) => {
-                        // FIXME: perf problem described in #55921.
-                        ui = ty::UniverseIndex::ROOT;
+                        if !self.infcx.unwrap().tcx.sess.opts.debugging_opts.chalk {
+                            // FIXME: perf problem described in #55921.
+                            ui = ty::UniverseIndex::ROOT;
+                        }
                         self.canonicalize_ty_var(
                             CanonicalVarInfo {
                                 kind: CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)),
@@ -439,8 +441,10 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
                     // `ConstVar(vid)` is unresolved, track its universe index in the
                     // canonicalized result
                     Err(mut ui) => {
-                        // FIXME: perf problem described in #55921.
-                        ui = ty::UniverseIndex::ROOT;
+                        if !self.infcx.unwrap().tcx.sess.opts.debugging_opts.chalk {
+                            // FIXME: perf problem described in #55921.
+                            ui = ty::UniverseIndex::ROOT;
+                        }
                         return self.canonicalize_const_var(
                             CanonicalVarInfo { kind: CanonicalVarKind::Const(ui) },
                             ct,
diff --git a/src/librustc_infer/infer/mod.rs b/src/librustc_infer/infer/mod.rs
index 2cf9dd882e4..67632a97df7 100644
--- a/src/librustc_infer/infer/mod.rs
+++ b/src/librustc_infer/infer/mod.rs
@@ -10,7 +10,6 @@ pub(crate) use self::undo_log::{InferCtxtUndoLogs, Snapshot, UndoLog};
 
 use crate::traits::{self, ObligationCause, PredicateObligations, TraitEngine};
 
-use rustc_ast::ast;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::undo_log::Rollback;
@@ -457,7 +456,7 @@ pub enum SubregionOrigin<'tcx> {
     /// the containing trait.
     CompareImplMethodObligation {
         span: Span,
-        item_name: ast::Name,
+        item_name: Symbol,
         impl_item_def_id: DefId,
         trait_item_def_id: DefId,
     },
@@ -519,7 +518,7 @@ pub enum RegionVariableOrigin {
 
     UpvarRegion(ty::UpvarId, Span),
 
-    BoundRegionInCoherence(ast::Name),
+    BoundRegionInCoherence(Symbol),
 
     /// This origin is used for the inference variables that we create
     /// during NLL region processing.
diff --git a/src/librustc_infer/traits/error_reporting/mod.rs b/src/librustc_infer/traits/error_reporting/mod.rs
index 2ae7b2ff925..f873358ff9f 100644
--- a/src/librustc_infer/traits/error_reporting/mod.rs
+++ b/src/librustc_infer/traits/error_reporting/mod.rs
@@ -1,12 +1,12 @@
 use super::ObjectSafetyViolation;
 
 use crate::infer::InferCtxt;
-use rustc_ast::ast;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_middle::ty::TyCtxt;
+use rustc_span::symbol::Symbol;
 use rustc_span::Span;
 use std::fmt;
 
@@ -14,7 +14,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     pub fn report_extra_impl_obligation(
         &self,
         error_span: Span,
-        item_name: ast::Name,
+        item_name: Symbol,
         _impl_item_def_id: DefId,
         trait_item_def_id: DefId,
         requirement: &dyn fmt::Display,
diff --git a/src/librustc_interface/tests.rs b/src/librustc_interface/tests.rs
index 1c20ea9e824..de304bcec23 100644
--- a/src/librustc_interface/tests.rs
+++ b/src/librustc_interface/tests.rs
@@ -525,6 +525,7 @@ fn test_debugging_options_tracking_hash() {
     tracked!(always_encode_mir, true);
     tracked!(asm_comments, true);
     tracked!(binary_dep_depinfo, true);
+    tracked!(chalk, true);
     tracked!(codegen_backend, Some("abc".to_string()));
     tracked!(crate_attr, vec!["abc".to_string()]);
     tracked!(debug_macros, true);
@@ -570,6 +571,7 @@ fn test_debugging_options_tracking_hash() {
     tracked!(tls_model, Some(TlsModel::GeneralDynamic));
     tracked!(treat_err_as_bug, Some(1));
     tracked!(unleash_the_miri_inside_of_you, true);
+    tracked!(use_ctors_section, Some(true));
     tracked!(verify_llvm_ir, true);
 }
 
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index cad6a312521..7d5289cd46f 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -41,7 +41,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_session::lint::FutureIncompatibleInfo;
 use rustc_span::edition::Edition;
 use rustc_span::source_map::Spanned;
-use rustc_span::symbol::{kw, sym, Symbol};
+use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{BytePos, Span};
 use rustc_target::abi::VariantIdx;
 use rustc_trait_selection::traits::misc::can_type_implement_copy;
@@ -1428,7 +1428,7 @@ impl KeywordIdents {
         &mut self,
         cx: &EarlyContext<'_>,
         UnderMacro(under_macro): UnderMacro,
-        ident: ast::Ident,
+        ident: Ident,
     ) {
         let next_edition = match cx.sess.edition() {
             Edition::Edition2015 => {
@@ -1482,7 +1482,7 @@ impl EarlyLintPass for KeywordIdents {
     fn check_mac(&mut self, cx: &EarlyContext<'_>, mac: &ast::MacCall) {
         self.check_tokens(cx, mac.args.inner_tokens());
     }
-    fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: ast::Ident) {
+    fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: Ident) {
         self.check_ident_token(cx, UnderMacro(false), ident);
     }
 }
diff --git a/src/librustc_lint/early.rs b/src/librustc_lint/early.rs
index 018e9da243c..06987ffa3d5 100644
--- a/src/librustc_lint/early.rs
+++ b/src/librustc_lint/early.rs
@@ -20,6 +20,7 @@ use rustc_ast::ast;
 use rustc_ast::visit as ast_visit;
 use rustc_session::lint::{BufferedEarlyLint, LintBuffer, LintPass};
 use rustc_session::Session;
+use rustc_span::symbol::Ident;
 use rustc_span::Span;
 
 use log::debug;
@@ -159,7 +160,7 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
         ast_visit::walk_ty(self, t);
     }
 
-    fn visit_ident(&mut self, ident: ast::Ident) {
+    fn visit_ident(&mut self, ident: Ident) {
         run_early_pass!(self, check_ident, ident);
     }
 
diff --git a/src/librustc_lint/internal.rs b/src/librustc_lint/internal.rs
index 6de8fb45d22..12b7459e88d 100644
--- a/src/librustc_lint/internal.rs
+++ b/src/librustc_lint/internal.rs
@@ -2,13 +2,13 @@
 //! Clippy.
 
 use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
-use rustc_ast::ast::{Ident, Item, ItemKind};
+use rustc_ast::ast::{Item, ItemKind};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::Applicability;
 use rustc_hir::{GenericArg, HirId, MutTy, Mutability, Path, PathSegment, QPath, Ty, TyKind};
 use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass};
 use rustc_span::hygiene::{ExpnKind, MacroKind};
-use rustc_span::symbol::{sym, Symbol};
+use rustc_span::symbol::{sym, Ident, Symbol};
 
 declare_tool_lint! {
     pub rustc::DEFAULT_HASH_TYPES,
diff --git a/src/librustc_lint/late.rs b/src/librustc_lint/late.rs
index c4ac875fec5..c8f827b1f5c 100644
--- a/src/librustc_lint/late.rs
+++ b/src/librustc_lint/late.rs
@@ -25,6 +25,7 @@ use rustc_hir::intravisit::Visitor;
 use rustc_middle::hir::map::Map;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_session::lint::LintPass;
+use rustc_span::symbol::Symbol;
 use rustc_span::Span;
 
 use log::debug;
@@ -192,7 +193,7 @@ impl<'a, 'tcx, T: LateLintPass<'a, 'tcx>> hir_visit::Visitor<'tcx>
     fn visit_variant_data(
         &mut self,
         s: &'tcx hir::VariantData<'tcx>,
-        _: ast::Name,
+        _: Symbol,
         _: &'tcx hir::Generics<'tcx>,
         _: hir::HirId,
         _: Span,
@@ -227,7 +228,7 @@ impl<'a, 'tcx, T: LateLintPass<'a, 'tcx>> hir_visit::Visitor<'tcx>
         hir_visit::walk_ty(self, t);
     }
 
-    fn visit_name(&mut self, sp: Span, name: ast::Name) {
+    fn visit_name(&mut self, sp: Span, name: Symbol) {
         lint_callback!(self, check_name, sp, name);
     }
 
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index 521a0d67b59..b791d313fc4 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -64,6 +64,7 @@ use rustc_session::lint::builtin::{
     INTRA_DOC_LINK_RESOLUTION_FAILURE, INVALID_CODEBLOCK_ATTRIBUTE, MISSING_DOC_CODE_EXAMPLES,
     PRIVATE_DOC_TESTS,
 };
+use rustc_span::symbol::{Ident, Symbol};
 use rustc_span::Span;
 
 use array_into_iter::ArrayIntoIter;
diff --git a/src/librustc_lint/non_ascii_idents.rs b/src/librustc_lint/non_ascii_idents.rs
index 94fc1a228df..ad02b2637d2 100644
--- a/src/librustc_lint/non_ascii_idents.rs
+++ b/src/librustc_lint/non_ascii_idents.rs
@@ -1,7 +1,7 @@
 use crate::{EarlyContext, EarlyLintPass, LintContext};
 use rustc_ast::ast;
 use rustc_data_structures::fx::FxHashMap;
-use rustc_span::symbol::SymbolStr;
+use rustc_span::symbol::{Ident, SymbolStr};
 use std::hash::{Hash, Hasher};
 use std::ops::Deref;
 
@@ -155,7 +155,7 @@ impl EarlyLintPass for NonAsciiIdents {
                 .or_insert((symbol_str, sp));
         }
     }
-    fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: ast::Ident) {
+    fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: Ident) {
         use unicode_security::GeneralSecurityProfile;
         let name_str = ident.name.as_str();
         if name_str.is_ascii() {
diff --git a/src/librustc_lint/passes.rs b/src/librustc_lint/passes.rs
index c9e12afedbb..04a398a29ba 100644
--- a/src/librustc_lint/passes.rs
+++ b/src/librustc_lint/passes.rs
@@ -5,6 +5,7 @@ use rustc_data_structures::sync;
 use rustc_hir as hir;
 use rustc_session::lint::builtin::HardwiredLints;
 use rustc_session::lint::LintPass;
+use rustc_span::symbol::{Ident, Symbol};
 use rustc_span::Span;
 
 #[macro_export]
@@ -14,7 +15,7 @@ macro_rules! late_lint_methods {
             fn check_param(a: &$hir hir::Param<$hir>);
             fn check_body(a: &$hir hir::Body<$hir>);
             fn check_body_post(a: &$hir hir::Body<$hir>);
-            fn check_name(a: Span, b: ast::Name);
+            fn check_name(a: Span, b: Symbol);
             fn check_crate(a: &$hir hir::Crate<$hir>);
             fn check_crate_post(a: &$hir hir::Crate<$hir>);
             fn check_mod(a: &$hir hir::Mod<$hir>, b: Span, c: hir::HirId);
@@ -155,7 +156,7 @@ macro_rules! early_lint_methods {
     ($macro:path, $args:tt) => (
         $macro!($args, [
             fn check_param(a: &ast::Param);
-            fn check_ident(a: ast::Ident);
+            fn check_ident(a: Ident);
             fn check_crate(a: &ast::Crate);
             fn check_crate_post(a: &ast::Crate);
             fn check_mod(a: &ast::Mod, b: Span, c: ast::NodeId);
diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs
index 04f17230717..32149c0afd5 100644
--- a/src/librustc_metadata/rmeta/decoder.rs
+++ b/src/librustc_metadata/rmeta/decoder.rs
@@ -4,7 +4,7 @@ use crate::creader::CrateMetadataRef;
 use crate::rmeta::table::{FixedSizeEncoding, Table};
 use crate::rmeta::*;
 
-use rustc_ast::ast::{self, Ident};
+use rustc_ast::ast;
 use rustc_attr as attr;
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fingerprint::Fingerprint;
@@ -33,7 +33,7 @@ use rustc_middle::util::common::record_time;
 use rustc_serialize::{opaque, Decodable, Decoder, SpecializedDecoder};
 use rustc_session::Session;
 use rustc_span::source_map::{respan, Spanned};
-use rustc_span::symbol::{sym, Symbol};
+use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::{self, hygiene::MacroKind, BytePos, Pos, Span, DUMMY_SP};
 
 use log::debug;
@@ -917,7 +917,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
     }
 
     /// Iterates over all the stability attributes in the given crate.
-    fn get_lib_features(&self, tcx: TyCtxt<'tcx>) -> &'tcx [(ast::Name, Option<ast::Name>)] {
+    fn get_lib_features(&self, tcx: TyCtxt<'tcx>) -> &'tcx [(Symbol, Option<Symbol>)] {
         // FIXME: For a proc macro crate, not sure whether we should return the "host"
         // features or an empty Vec. Both don't cause ICEs.
         tcx.arena.alloc_from_iter(self.root.lib_features.decode(self))
@@ -1205,7 +1205,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
             .collect::<Vec<_>>()
     }
 
-    fn get_struct_field_names(&self, id: DefIndex, sess: &Session) -> Vec<Spanned<ast::Name>> {
+    fn get_struct_field_names(&self, id: DefIndex, sess: &Session) -> Vec<Spanned<Symbol>> {
         self.root
             .tables
             .children
@@ -1317,7 +1317,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         }
     }
 
-    fn get_fn_param_names(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> &'tcx [ast::Name] {
+    fn get_fn_param_names(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> &'tcx [Symbol] {
         let param_names = match self.kind(id) {
             EntryKind::Fn(data) | EntryKind::ForeignFn(data) => data.decode(self).param_names,
             EntryKind::AssocFn(data) => data.decode(self).fn_data.param_names,
diff --git a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs
index c6c06c98ee5..b18272675c0 100644
--- a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs
+++ b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs
@@ -21,7 +21,7 @@ use rustc_middle::ty::query::QueryConfig;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_session::{CrateDisambiguator, Session};
 use rustc_span::source_map::{self, Span, Spanned};
-use rustc_span::symbol::Symbol;
+use rustc_span::symbol::{Ident, Symbol};
 
 use rustc_data_structures::sync::Lrc;
 use smallvec::SmallVec;
@@ -419,7 +419,7 @@ impl CStore {
             .disambiguated_data
             .data
             .get_opt_name()
-            .map(ast::Ident::with_dummy_span) // FIXME: cross-crate hygiene
+            .map(Ident::with_dummy_span) // FIXME: cross-crate hygiene
             .expect("no name in load_macro");
 
         LoadedMacro::MacroDef(
diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs
index 4ac2092bb06..2589e162dff 100644
--- a/src/librustc_metadata/rmeta/encoder.rs
+++ b/src/librustc_metadata/rmeta/encoder.rs
@@ -2,7 +2,7 @@ use crate::rmeta::table::FixedSizeEncoding;
 use crate::rmeta::*;
 
 use log::{debug, trace};
-use rustc_ast::ast::{self, Ident};
+use rustc_ast::ast;
 use rustc_ast::attr;
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -32,7 +32,7 @@ use rustc_middle::ty::{self, SymbolName, Ty, TyCtxt};
 use rustc_serialize::{opaque, Encodable, Encoder, SpecializedEncoder};
 use rustc_session::config::CrateType;
 use rustc_span::source_map::Spanned;
-use rustc_span::symbol::{kw, sym, Symbol};
+use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{self, ExternalSource, FileName, SourceFile, Span};
 use rustc_target::abi::VariantIdx;
 use std::hash::Hash;
@@ -989,7 +989,7 @@ impl EncodeContext<'tcx> {
         }
     }
 
-    fn encode_fn_param_names_for_body(&mut self, body_id: hir::BodyId) -> Lazy<[ast::Name]> {
+    fn encode_fn_param_names_for_body(&mut self, body_id: hir::BodyId) -> Lazy<[Symbol]> {
         self.tcx.dep_graph.with_ignore(|| {
             let body = self.tcx.hir().body(body_id);
             self.lazy(body.params.iter().map(|arg| match arg.pat.kind {
@@ -999,7 +999,7 @@ impl EncodeContext<'tcx> {
         })
     }
 
-    fn encode_fn_param_names(&mut self, param_names: &[ast::Ident]) -> Lazy<[ast::Name]> {
+    fn encode_fn_param_names(&mut self, param_names: &[Ident]) -> Lazy<[Symbol]> {
         self.lazy(param_names.iter().map(|ident| ident.name))
     }
 
@@ -1410,7 +1410,7 @@ impl EncodeContext<'tcx> {
         self.lazy(deps.iter().map(|&(_, ref dep)| dep))
     }
 
-    fn encode_lib_features(&mut self) -> Lazy<[(ast::Name, Option<ast::Name>)]> {
+    fn encode_lib_features(&mut self) -> Lazy<[(Symbol, Option<Symbol>)]> {
         let tcx = self.tcx;
         let lib_features = tcx.lib_features();
         self.lazy(lib_features.to_vec())
diff --git a/src/librustc_metadata/rmeta/mod.rs b/src/librustc_metadata/rmeta/mod.rs
index e2d979ae488..66930761205 100644
--- a/src/librustc_metadata/rmeta/mod.rs
+++ b/src/librustc_metadata/rmeta/mod.rs
@@ -215,7 +215,7 @@ crate struct CrateRoot<'tcx> {
 
 #[derive(RustcEncodable, RustcDecodable)]
 crate struct CrateDep {
-    pub name: ast::Name,
+    pub name: Symbol,
     pub hash: Svh,
     pub host_hash: Option<Svh>,
     pub kind: DepKind,
@@ -327,7 +327,7 @@ struct ModData {
 struct FnData {
     asyncness: hir::IsAsync,
     constness: hir::Constness,
-    param_names: Lazy<[ast::Name]>,
+    param_names: Lazy<[Symbol]>,
 }
 
 #[derive(RustcEncodable, RustcDecodable)]
diff --git a/src/librustc_middle/Cargo.toml b/src/librustc_middle/Cargo.toml
index 398ba4d72d4..8a1317ba289 100644
--- a/src/librustc_middle/Cargo.toml
+++ b/src/librustc_middle/Cargo.toml
@@ -31,6 +31,7 @@ rustc_serialize = { path = "../libserialize", package = "serialize" }
 rustc_ast = { path = "../librustc_ast" }
 rustc_span = { path = "../librustc_span" }
 byteorder = { version = "1.3" }
+chalk-ir = "0.10.0"
 smallvec = { version = "1.0", features = ["union", "may_dangle"] }
 measureme = "0.7.1"
 rustc_session = { path = "../librustc_session" }
diff --git a/src/librustc_middle/arena.rs b/src/librustc_middle/arena.rs
index 96ef4b37412..a97db3134dc 100644
--- a/src/librustc_middle/arena.rs
+++ b/src/librustc_middle/arena.rs
@@ -65,7 +65,7 @@ macro_rules! arena_types {
             [] object_safety_violations: rustc_middle::traits::ObjectSafetyViolation,
             [] codegen_unit: rustc_middle::mir::mono::CodegenUnit<$tcx>,
             [] attribute: rustc_ast::ast::Attribute,
-            [] name_set: rustc_data_structures::fx::FxHashSet<rustc_ast::ast::Name>,
+            [] name_set: rustc_data_structures::fx::FxHashSet<rustc_span::symbol::Symbol>,
             [] hir_id_set: rustc_hir::HirIdSet,
 
             // Interned types
diff --git a/src/librustc_middle/dep_graph/dep_node.rs b/src/librustc_middle/dep_graph/dep_node.rs
index 19b85aa3c51..33037900880 100644
--- a/src/librustc_middle/dep_graph/dep_node.rs
+++ b/src/librustc_middle/dep_graph/dep_node.rs
@@ -51,6 +51,7 @@
 
 use crate::mir;
 use crate::mir::interpret::{GlobalId, LitToConstInput};
+use crate::traits;
 use crate::traits::query::{
     CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal,
     CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal,
diff --git a/src/librustc_middle/hir/exports.rs b/src/librustc_middle/hir/exports.rs
index 4c144a54d63..83baf6cc433 100644
--- a/src/librustc_middle/hir/exports.rs
+++ b/src/librustc_middle/hir/exports.rs
@@ -1,9 +1,9 @@
 use crate::ty;
 
-use rustc_ast::ast;
 use rustc_hir::def::Res;
 use rustc_hir::def_id::DefIdMap;
 use rustc_macros::HashStable;
+use rustc_span::symbol::Ident;
 use rustc_span::Span;
 
 use std::fmt::Debug;
@@ -15,7 +15,7 @@ pub type ExportMap<Id> = DefIdMap<Vec<Export<Id>>>;
 #[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub struct Export<Id> {
     /// The name of the target.
-    pub ident: ast::Ident,
+    pub ident: Ident,
     /// The resolution of the target.
     pub res: Res<Id>,
     /// The span of the target.
diff --git a/src/librustc_middle/hir/map/blocks.rs b/src/librustc_middle/hir/map/blocks.rs
index 7024e86f95d..a2e4372f017 100644
--- a/src/librustc_middle/hir/map/blocks.rs
+++ b/src/librustc_middle/hir/map/blocks.rs
@@ -12,10 +12,11 @@
 //! for the `Code` associated with a particular NodeId.
 
 use crate::hir::map::Map;
-use rustc_ast::ast::{Attribute, Ident};
+use rustc_ast::ast::Attribute;
 use rustc_hir as hir;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{Expr, FnDecl, Node};
+use rustc_span::symbol::Ident;
 use rustc_span::Span;
 
 /// An FnLikeNode is a Node that is like a fn, in that it has a decl
diff --git a/src/librustc_middle/hir/map/mod.rs b/src/librustc_middle/hir/map/mod.rs
index 235d1d80192..de0373c1384 100644
--- a/src/librustc_middle/hir/map/mod.rs
+++ b/src/librustc_middle/hir/map/mod.rs
@@ -3,7 +3,7 @@ use self::collector::NodeCollector;
 use crate::hir::{Owner, OwnerNodes};
 use crate::ty::query::Providers;
 use crate::ty::TyCtxt;
-use rustc_ast::ast::{self, Name, NodeId};
+use rustc_ast::ast::{self, NodeId};
 use rustc_data_structures::svh::Svh;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
@@ -14,7 +14,7 @@ use rustc_hir::*;
 use rustc_index::vec::IndexVec;
 use rustc_span::hygiene::MacroKind;
 use rustc_span::source_map::Spanned;
-use rustc_span::symbol::kw;
+use rustc_span::symbol::{kw, Symbol};
 use rustc_span::Span;
 use rustc_target::spec::abi::Abi;
 
@@ -452,7 +452,7 @@ impl<'hir> Map<'hir> {
         }
     }
 
-    pub fn ty_param_name(&self, id: HirId) -> Name {
+    pub fn ty_param_name(&self, id: HirId) -> Symbol {
         match self.get(id) {
             Node::Item(&Item { kind: ItemKind::Trait(..) | ItemKind::TraitAlias(..), .. }) => {
                 kw::SelfUpper
@@ -824,7 +824,7 @@ impl<'hir> Map<'hir> {
         }
     }
 
-    pub fn opt_name(&self, id: HirId) -> Option<Name> {
+    pub fn opt_name(&self, id: HirId) -> Option<Symbol> {
         Some(match self.get(id) {
             Node::Item(i) => i.ident.name,
             Node::ForeignItem(fi) => fi.ident.name,
@@ -840,7 +840,7 @@ impl<'hir> Map<'hir> {
         })
     }
 
-    pub fn name(&self, id: HirId) -> Name {
+    pub fn name(&self, id: HirId) -> Symbol {
         match self.opt_name(id) {
             Some(name) => name,
             None => bug!("no name for {}", self.node_to_string(id)),
@@ -952,42 +952,42 @@ impl<'hir> intravisit::Map<'hir> for Map<'hir> {
 }
 
 trait Named {
-    fn name(&self) -> Name;
+    fn name(&self) -> Symbol;
 }
 
 impl<T: Named> Named for Spanned<T> {
-    fn name(&self) -> Name {
+    fn name(&self) -> Symbol {
         self.node.name()
     }
 }
 
 impl Named for Item<'_> {
-    fn name(&self) -> Name {
+    fn name(&self) -> Symbol {
         self.ident.name
     }
 }
 impl Named for ForeignItem<'_> {
-    fn name(&self) -> Name {
+    fn name(&self) -> Symbol {
         self.ident.name
     }
 }
 impl Named for Variant<'_> {
-    fn name(&self) -> Name {
+    fn name(&self) -> Symbol {
         self.ident.name
     }
 }
 impl Named for StructField<'_> {
-    fn name(&self) -> Name {
+    fn name(&self) -> Symbol {
         self.ident.name
     }
 }
 impl Named for TraitItem<'_> {
-    fn name(&self) -> Name {
+    fn name(&self) -> Symbol {
         self.ident.name
     }
 }
 impl Named for ImplItem<'_> {
-    fn name(&self) -> Name {
+    fn name(&self) -> Symbol {
         self.ident.name
     }
 }
diff --git a/src/librustc_middle/ich/impls_ty.rs b/src/librustc_middle/ich/impls_ty.rs
index 226277e440a..377c8661cbd 100644
--- a/src/librustc_middle/ich/impls_ty.rs
+++ b/src/librustc_middle/ich/impls_ty.rs
@@ -136,8 +136,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::AllocId {
         ty::tls::with_opt(|tcx| {
             trace!("hashing {:?}", *self);
             let tcx = tcx.expect("can't hash AllocIds during hir lowering");
-            let alloc_kind = tcx.alloc_map.lock().get(*self);
-            alloc_kind.hash_stable(hcx, hasher);
+            tcx.get_global_alloc(*self).hash_stable(hcx, hasher);
         });
     }
 }
diff --git a/src/librustc_middle/lib.rs b/src/librustc_middle/lib.rs
index 9b38b43c93a..b17a77e0f6f 100644
--- a/src/librustc_middle/lib.rs
+++ b/src/librustc_middle/lib.rs
@@ -42,6 +42,7 @@
 #![feature(or_patterns)]
 #![feature(range_is_empty)]
 #![feature(specialization)]
+#![feature(track_caller)]
 #![feature(trusted_len)]
 #![feature(vec_remove_item)]
 #![feature(stmt_expr_attributes)]
diff --git a/src/librustc_middle/mir/interpret/mod.rs b/src/librustc_middle/mir/interpret/mod.rs
index 61d7425de7d..71adb2fa477 100644
--- a/src/librustc_middle/mir/interpret/mod.rs
+++ b/src/librustc_middle/mir/interpret/mod.rs
@@ -197,9 +197,7 @@ pub fn specialized_encode_alloc_id<'tcx, E: Encoder>(
     tcx: TyCtxt<'tcx>,
     alloc_id: AllocId,
 ) -> Result<(), E::Error> {
-    let alloc: GlobalAlloc<'tcx> =
-        tcx.alloc_map.lock().get(alloc_id).expect("no value for given alloc ID");
-    match alloc {
+    match tcx.global_alloc(alloc_id) {
         GlobalAlloc::Memory(alloc) => {
             trace!("encoding {:?} with {:#?}", alloc_id, alloc);
             AllocDiscriminant::Alloc.encode(encoder)?;
@@ -294,7 +292,7 @@ impl<'s> AllocDecodingSession<'s> {
                         AllocDiscriminant::Alloc => {
                             // If this is an allocation, we need to reserve an
                             // `AllocId` so we can decode cyclic graphs.
-                            let alloc_id = decoder.tcx().alloc_map.lock().reserve();
+                            let alloc_id = decoder.tcx().reserve_alloc_id();
                             *entry =
                                 State::InProgress(TinyList::new_single(self.session_id), alloc_id);
                             Some(alloc_id)
@@ -338,7 +336,7 @@ impl<'s> AllocDecodingSession<'s> {
                     // We already have a reserved `AllocId`.
                     let alloc_id = alloc_id.unwrap();
                     trace!("decoded alloc {:?}: {:#?}", alloc_id, alloc);
-                    decoder.tcx().alloc_map.lock().set_alloc_id_same_memory(alloc_id, alloc);
+                    decoder.tcx().set_alloc_id_same_memory(alloc_id, alloc);
                     Ok(alloc_id)
                 }
                 AllocDiscriminant::Fn => {
@@ -346,7 +344,7 @@ impl<'s> AllocDecodingSession<'s> {
                     trace!("creating fn alloc ID");
                     let instance = ty::Instance::decode(decoder)?;
                     trace!("decoded fn alloc instance: {:?}", instance);
-                    let alloc_id = decoder.tcx().alloc_map.lock().create_fn_alloc(instance);
+                    let alloc_id = decoder.tcx().create_fn_alloc(instance);
                     Ok(alloc_id)
                 }
                 AllocDiscriminant::Static => {
@@ -354,7 +352,7 @@ impl<'s> AllocDecodingSession<'s> {
                     trace!("creating extern static alloc ID");
                     let did = DefId::decode(decoder)?;
                     trace!("decoded static def-ID: {:?}", did);
-                    let alloc_id = decoder.tcx().alloc_map.lock().create_static_alloc(did);
+                    let alloc_id = decoder.tcx().create_static_alloc(did);
                     Ok(alloc_id)
                 }
             }
@@ -381,7 +379,29 @@ pub enum GlobalAlloc<'tcx> {
     Memory(&'tcx Allocation),
 }
 
-pub struct AllocMap<'tcx> {
+impl GlobalAlloc<'tcx> {
+    /// Panics if the `GlobalAlloc` does not refer to an `GlobalAlloc::Memory`
+    #[track_caller]
+    #[inline]
+    pub fn unwrap_memory(&self) -> &'tcx Allocation {
+        match *self {
+            GlobalAlloc::Memory(mem) => mem,
+            _ => bug!("expected memory, got {:?}", self),
+        }
+    }
+
+    /// Panics if the `GlobalAlloc` is not `GlobalAlloc::Function`
+    #[track_caller]
+    #[inline]
+    pub fn unwrap_fn(&self) -> Instance<'tcx> {
+        match *self {
+            GlobalAlloc::Function(instance) => instance,
+            _ => bug!("expected function, got {:?}", self),
+        }
+    }
+}
+
+crate struct AllocMap<'tcx> {
     /// Maps `AllocId`s to their corresponding allocations.
     alloc_map: FxHashMap<AllocId, GlobalAlloc<'tcx>>,
 
@@ -397,16 +417,10 @@ pub struct AllocMap<'tcx> {
 }
 
 impl<'tcx> AllocMap<'tcx> {
-    pub fn new() -> Self {
+    crate fn new() -> Self {
         AllocMap { alloc_map: Default::default(), dedup: Default::default(), next_id: AllocId(0) }
     }
-
-    /// Obtains a new allocation ID that can be referenced but does not
-    /// yet have an allocation backing it.
-    ///
-    /// Make sure to call `set_alloc_id_memory` or `set_alloc_id_same_memory` before returning such
-    /// an `AllocId` from a query.
-    pub fn reserve(&mut self) -> AllocId {
+    fn reserve(&mut self) -> AllocId {
         let next = self.next_id;
         self.next_id.0 = self.next_id.0.checked_add(1).expect(
             "You overflowed a u64 by incrementing by 1... \
@@ -415,34 +429,46 @@ impl<'tcx> AllocMap<'tcx> {
         );
         next
     }
+}
+
+impl<'tcx> TyCtxt<'tcx> {
+    /// Obtains a new allocation ID that can be referenced but does not
+    /// yet have an allocation backing it.
+    ///
+    /// Make sure to call `set_alloc_id_memory` or `set_alloc_id_same_memory` before returning such
+    /// an `AllocId` from a query.
+    pub fn reserve_alloc_id(&self) -> AllocId {
+        self.alloc_map.lock().reserve()
+    }
 
     /// Reserves a new ID *if* this allocation has not been dedup-reserved before.
     /// Should only be used for function pointers and statics, we don't want
     /// to dedup IDs for "real" memory!
-    fn reserve_and_set_dedup(&mut self, alloc: GlobalAlloc<'tcx>) -> AllocId {
+    fn reserve_and_set_dedup(&self, alloc: GlobalAlloc<'tcx>) -> AllocId {
+        let mut alloc_map = self.alloc_map.lock();
         match alloc {
             GlobalAlloc::Function(..) | GlobalAlloc::Static(..) => {}
             GlobalAlloc::Memory(..) => bug!("Trying to dedup-reserve memory with real data!"),
         }
-        if let Some(&alloc_id) = self.dedup.get(&alloc) {
+        if let Some(&alloc_id) = alloc_map.dedup.get(&alloc) {
             return alloc_id;
         }
-        let id = self.reserve();
+        let id = alloc_map.reserve();
         debug!("creating alloc {:?} with id {}", alloc, id);
-        self.alloc_map.insert(id, alloc.clone());
-        self.dedup.insert(alloc, id);
+        alloc_map.alloc_map.insert(id, alloc.clone());
+        alloc_map.dedup.insert(alloc, id);
         id
     }
 
     /// Generates an `AllocId` for a static or return a cached one in case this function has been
     /// called on the same static before.
-    pub fn create_static_alloc(&mut self, static_id: DefId) -> AllocId {
+    pub fn create_static_alloc(&self, static_id: DefId) -> AllocId {
         self.reserve_and_set_dedup(GlobalAlloc::Static(static_id))
     }
 
     /// Generates an `AllocId` for a function.  Depending on the function type,
     /// this might get deduplicated or assigned a new ID each time.
-    pub fn create_fn_alloc(&mut self, instance: Instance<'tcx>) -> AllocId {
+    pub fn create_fn_alloc(&self, instance: Instance<'tcx>) -> AllocId {
         // Functions cannot be identified by pointers, as asm-equal functions can get deduplicated
         // by the linker (we set the "unnamed_addr" attribute for LLVM) and functions can be
         // duplicated across crates.
@@ -456,8 +482,9 @@ impl<'tcx> AllocMap<'tcx> {
         });
         if is_generic {
             // Get a fresh ID.
-            let id = self.reserve();
-            self.alloc_map.insert(id, GlobalAlloc::Function(instance));
+            let mut alloc_map = self.alloc_map.lock();
+            let id = alloc_map.reserve();
+            alloc_map.alloc_map.insert(id, GlobalAlloc::Function(instance));
             id
         } else {
             // Deduplicate.
@@ -470,8 +497,8 @@ impl<'tcx> AllocMap<'tcx> {
     /// Statics with identical content will still point to the same `Allocation`, i.e.,
     /// their data will be deduplicated through `Allocation` interning -- but they
     /// are different places in memory and as such need different IDs.
-    pub fn create_memory_alloc(&mut self, mem: &'tcx Allocation) -> AllocId {
-        let id = self.reserve();
+    pub fn create_memory_alloc(&self, mem: &'tcx Allocation) -> AllocId {
+        let id = self.reserve_alloc_id();
         self.set_alloc_id_memory(id, mem);
         id
     }
@@ -482,38 +509,35 @@ impl<'tcx> AllocMap<'tcx> {
     /// This function exists to allow const eval to detect the difference between evaluation-
     /// local dangling pointers and allocations in constants/statics.
     #[inline]
-    pub fn get(&self, id: AllocId) -> Option<GlobalAlloc<'tcx>> {
-        self.alloc_map.get(&id).cloned()
-    }
-
-    /// Panics if the `AllocId` does not refer to an `Allocation`
-    pub fn unwrap_memory(&self, id: AllocId) -> &'tcx Allocation {
-        match self.get(id) {
-            Some(GlobalAlloc::Memory(mem)) => mem,
-            _ => bug!("expected allocation ID {} to point to memory", id),
-        }
+    pub fn get_global_alloc(&self, id: AllocId) -> Option<GlobalAlloc<'tcx>> {
+        self.alloc_map.lock().alloc_map.get(&id).cloned()
     }
 
-    /// Panics if the `AllocId` does not refer to a function
-    pub fn unwrap_fn(&self, id: AllocId) -> Instance<'tcx> {
-        match self.get(id) {
-            Some(GlobalAlloc::Function(instance)) => instance,
-            _ => bug!("expected allocation ID {} to point to a function", id),
+    #[inline]
+    #[track_caller]
+    /// Panics in case the `AllocId` is dangling. Since that is impossible for `AllocId`s in
+    /// constants (as all constants must pass interning and validation that check for dangling
+    /// ids), this function is frequently used throughout rustc, but should not be used within
+    /// the miri engine.
+    pub fn global_alloc(&self, id: AllocId) -> GlobalAlloc<'tcx> {
+        match self.get_global_alloc(id) {
+            Some(alloc) => alloc,
+            None => bug!("could not find allocation for {}", id),
         }
     }
 
     /// Freezes an `AllocId` created with `reserve` by pointing it at an `Allocation`. Trying to
     /// call this function twice, even with the same `Allocation` will ICE the compiler.
-    pub fn set_alloc_id_memory(&mut self, id: AllocId, mem: &'tcx Allocation) {
-        if let Some(old) = self.alloc_map.insert(id, GlobalAlloc::Memory(mem)) {
+    pub fn set_alloc_id_memory(&self, id: AllocId, mem: &'tcx Allocation) {
+        if let Some(old) = self.alloc_map.lock().alloc_map.insert(id, GlobalAlloc::Memory(mem)) {
             bug!("tried to set allocation ID {}, but it was already existing as {:#?}", id, old);
         }
     }
 
     /// Freezes an `AllocId` created with `reserve` by pointing it at an `Allocation`. May be called
     /// twice for the same `(AllocId, Allocation)` pair.
-    fn set_alloc_id_same_memory(&mut self, id: AllocId, mem: &'tcx Allocation) {
-        self.alloc_map.insert_same(id, GlobalAlloc::Memory(mem));
+    fn set_alloc_id_same_memory(&self, id: AllocId, mem: &'tcx Allocation) {
+        self.alloc_map.lock().alloc_map.insert_same(id, GlobalAlloc::Memory(mem));
     }
 }
 
diff --git a/src/librustc_middle/mir/mod.rs b/src/librustc_middle/mir/mod.rs
index 15862660512..62e6e124981 100644
--- a/src/librustc_middle/mir/mod.rs
+++ b/src/librustc_middle/mir/mod.rs
@@ -19,7 +19,6 @@ use rustc_target::abi::VariantIdx;
 
 use polonius_engine::Atom;
 pub use rustc_ast::ast::Mutability;
-use rustc_ast::ast::Name;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::graph::dominators::{dominators, Dominators};
 use rustc_data_structures::graph::{self, GraphSuccessors};
@@ -968,7 +967,7 @@ impl<'tcx> LocalDecl<'tcx> {
 /// Debug information pertaining to a user variable.
 #[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
 pub struct VarDebugInfo<'tcx> {
-    pub name: Name,
+    pub name: Symbol,
 
     /// Source info of the user variable, including the scope
     /// within which the variable is visible (to debuginfo)
@@ -2404,13 +2403,9 @@ pub struct Constant<'tcx> {
 impl Constant<'tcx> {
     pub fn check_static_ptr(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
         match self.literal.val.try_to_scalar() {
-            Some(Scalar::Ptr(ptr)) => match tcx.alloc_map.lock().get(ptr.alloc_id) {
-                Some(GlobalAlloc::Static(def_id)) => Some(def_id),
-                Some(_) => None,
-                None => {
-                    tcx.sess.delay_span_bug(DUMMY_SP, "MIR cannot contain dangling const pointers");
-                    None
-                }
+            Some(Scalar::Ptr(ptr)) => match tcx.global_alloc(ptr.alloc_id) {
+                GlobalAlloc::Static(def_id) => Some(def_id),
+                _ => None,
             },
             _ => None,
         }
diff --git a/src/librustc_middle/query/mod.rs b/src/librustc_middle/query/mod.rs
index b0c44238148..2ceba519494 100644
--- a/src/librustc_middle/query/mod.rs
+++ b/src/librustc_middle/query/mod.rs
@@ -1,6 +1,7 @@
 use crate::dep_graph::SerializedDepNodeIndex;
 use crate::mir;
 use crate::mir::interpret::{GlobalId, LitToConstInput};
+use crate::traits;
 use crate::traits::query::{
     CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal,
     CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal,
@@ -639,7 +640,7 @@ rustc_queries! {
     }
 
     Other {
-        query fn_arg_names(_: DefId) -> &'tcx [ast::Name] {}
+        query fn_arg_names(_: DefId) -> &'tcx [Symbol] {}
         /// Gets the rendered value of the specified constant or associated constant.
         /// Used by rustdoc.
         query rendered_const(_: DefId) -> String {}
@@ -1052,7 +1053,7 @@ rustc_queries! {
             desc { "looking up all possibly unused extern crates" }
         }
         query names_imported_by_glob_use(def_id: LocalDefId)
-            -> &'tcx FxHashSet<ast::Name> {
+            -> &'tcx FxHashSet<Symbol> {
             eval_always
             desc { |tcx| "names_imported_by_glob_use for `{}`", tcx.def_path_str(def_id.to_def_id()) }
         }
@@ -1154,6 +1155,15 @@ rustc_queries! {
             desc { "evaluating trait selection obligation `{}`", goal.value.value }
         }
 
+        query evaluate_goal(
+            goal: traits::ChalkCanonicalGoal<'tcx>
+        ) -> Result<
+            &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>,
+            NoSolution
+        > {
+            desc { "evaluating trait selection obligation `{}`", goal.value }
+        }
+
         /// Do not call this query directly: part of the `Eq` type-op
         query type_op_ascribe_user_type(
             goal: CanonicalTypeOpAscribeUserTypeGoal<'tcx>
diff --git a/src/librustc_middle/traits/chalk.rs b/src/librustc_middle/traits/chalk.rs
new file mode 100644
index 00000000000..b963af96f50
--- /dev/null
+++ b/src/librustc_middle/traits/chalk.rs
@@ -0,0 +1,366 @@
+//! Types required for Chalk-related queries
+//!
+//! The primary purpose of this file is defining an implementation for the
+//! `chalk_ir::interner::Interner` trait. The primary purpose of this trait, as
+//! its name suggest, is to provide an abstraction boundary for creating
+//! interned Chalk types.
+
+use chalk_ir::{GoalData, Parameter};
+
+use rustc_middle::mir::Mutability;
+use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
+use rustc_middle::ty::{self, Ty, TyCtxt};
+
+use rustc_hir::def_id::DefId;
+
+use smallvec::SmallVec;
+
+use std::cmp::Ordering;
+use std::fmt;
+use std::hash::{Hash, Hasher};
+
+/// Since Chalk doesn't have full support for all Rust builtin types yet, we
+/// need to use an enum here, rather than just `DefId`.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
+pub enum RustDefId {
+    Adt(DefId),
+    Str,
+    Never,
+    Slice,
+    Array,
+    Ref(Mutability),
+    RawPtr,
+
+    Trait(DefId),
+
+    Impl(DefId),
+
+    FnDef(DefId),
+
+    AssocTy(DefId),
+}
+
+#[derive(Copy, Clone)]
+pub struct RustInterner<'tcx> {
+    pub tcx: TyCtxt<'tcx>,
+}
+
+/// We don't ever actually need this. It's only required for derives.
+impl<'tcx> Hash for RustInterner<'tcx> {
+    fn hash<H: Hasher>(&self, _state: &mut H) {}
+}
+
+/// We don't ever actually need this. It's only required for derives.
+impl<'tcx> Ord for RustInterner<'tcx> {
+    fn cmp(&self, _other: &Self) -> Ordering {
+        Ordering::Equal
+    }
+}
+
+/// We don't ever actually need this. It's only required for derives.
+impl<'tcx> PartialOrd for RustInterner<'tcx> {
+    fn partial_cmp(&self, _other: &Self) -> Option<Ordering> {
+        None
+    }
+}
+
+/// We don't ever actually need this. It's only required for derives.
+impl<'tcx> PartialEq for RustInterner<'tcx> {
+    fn eq(&self, _other: &Self) -> bool {
+        false
+    }
+}
+
+/// We don't ever actually need this. It's only required for derives.
+impl<'tcx> Eq for RustInterner<'tcx> {}
+
+impl fmt::Debug for RustInterner<'_> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "RustInterner")
+    }
+}
+
+// Right now, there is no interning at all. I was running into problems with
+// adding interning in `ty/context.rs` for Chalk types with
+// `parallel-compiler = true`. -jackh726
+impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> {
+    type InternedType = Box<chalk_ir::TyData<Self>>;
+    type InternedLifetime = Box<chalk_ir::LifetimeData<Self>>;
+    type InternedParameter = Box<chalk_ir::ParameterData<Self>>;
+    type InternedGoal = Box<chalk_ir::GoalData<Self>>;
+    type InternedGoals = Vec<chalk_ir::Goal<Self>>;
+    type InternedSubstitution = Vec<chalk_ir::Parameter<Self>>;
+    type InternedProgramClause = Box<chalk_ir::ProgramClauseData<Self>>;
+    type InternedProgramClauses = Vec<chalk_ir::ProgramClause<Self>>;
+    type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>;
+    type InternedParameterKinds = Vec<chalk_ir::ParameterKind<()>>;
+    type InternedCanonicalVarKinds = Vec<chalk_ir::ParameterKind<chalk_ir::UniverseIndex>>;
+    type DefId = RustDefId;
+    type Identifier = ();
+
+    fn debug_program_clause_implication(
+        pci: &chalk_ir::ProgramClauseImplication<Self>,
+        fmt: &mut fmt::Formatter<'_>,
+    ) -> Option<fmt::Result> {
+        let mut write = || {
+            write!(fmt, "{:?}", pci.consequence)?;
+
+            let conditions = pci.conditions.interned();
+
+            let conds = conditions.len();
+            if conds == 0 {
+                return Ok(());
+            }
+
+            write!(fmt, " :- ")?;
+            for cond in &conditions[..conds - 1] {
+                write!(fmt, "{:?}, ", cond)?;
+            }
+            write!(fmt, "{:?}", conditions[conds - 1])?;
+            Ok(())
+        };
+        Some(write())
+    }
+
+    fn debug_application_ty(
+        application_ty: &chalk_ir::ApplicationTy<Self>,
+        fmt: &mut fmt::Formatter<'_>,
+    ) -> Option<fmt::Result> {
+        let chalk_ir::ApplicationTy { name, substitution } = application_ty;
+        Some(write!(fmt, "{:?}{:?}", name, chalk_ir::debug::Angle(substitution.interned())))
+    }
+
+    fn debug_substitution(
+        substitution: &chalk_ir::Substitution<Self>,
+        fmt: &mut fmt::Formatter<'_>,
+    ) -> Option<fmt::Result> {
+        Some(write!(fmt, "{:?}", substitution.interned()))
+    }
+
+    fn debug_separator_trait_ref(
+        separator_trait_ref: &chalk_ir::SeparatorTraitRef<'_, Self>,
+        fmt: &mut fmt::Formatter<'_>,
+    ) -> Option<fmt::Result> {
+        let substitution = &separator_trait_ref.trait_ref.substitution;
+        let parameters = substitution.interned();
+        Some(write!(
+            fmt,
+            "{:?}{}{:?}{:?}",
+            parameters[0],
+            separator_trait_ref.separator,
+            separator_trait_ref.trait_ref.trait_id,
+            chalk_ir::debug::Angle(&parameters[1..])
+        ))
+    }
+
+    fn debug_quantified_where_clauses(
+        clauses: &chalk_ir::QuantifiedWhereClauses<Self>,
+        fmt: &mut fmt::Formatter<'_>,
+    ) -> Option<fmt::Result> {
+        Some(write!(fmt, "{:?}", clauses.interned()))
+    }
+
+    fn debug_alias(
+        alias_ty: &chalk_ir::AliasTy<Self>,
+        fmt: &mut fmt::Formatter<'_>,
+    ) -> Option<fmt::Result> {
+        match alias_ty {
+            chalk_ir::AliasTy::Projection(projection_ty) => {
+                Self::debug_projection_ty(projection_ty, fmt)
+            }
+            chalk_ir::AliasTy::Opaque(opaque_ty) => Self::debug_opaque_ty(opaque_ty, fmt),
+        }
+    }
+
+    fn debug_projection_ty(
+        projection_ty: &chalk_ir::ProjectionTy<Self>,
+        fmt: &mut fmt::Formatter<'_>,
+    ) -> Option<fmt::Result> {
+        Some(write!(
+            fmt,
+            "projection: {:?} {:?}",
+            projection_ty.associated_ty_id, projection_ty.substitution,
+        ))
+    }
+
+    fn debug_opaque_ty(
+        opaque_ty: &chalk_ir::OpaqueTy<Self>,
+        fmt: &mut fmt::Formatter<'_>,
+    ) -> Option<fmt::Result> {
+        Some(write!(fmt, "{:?}", opaque_ty.opaque_ty_id))
+    }
+
+    fn intern_ty(&self, ty: chalk_ir::TyData<Self>) -> Self::InternedType {
+        Box::new(ty)
+    }
+
+    fn ty_data<'a>(&self, ty: &'a Self::InternedType) -> &'a chalk_ir::TyData<Self> {
+        ty
+    }
+
+    fn intern_lifetime(&self, lifetime: chalk_ir::LifetimeData<Self>) -> Self::InternedLifetime {
+        Box::new(lifetime)
+    }
+
+    fn lifetime_data<'a>(
+        &self,
+        lifetime: &'a Self::InternedLifetime,
+    ) -> &'a chalk_ir::LifetimeData<Self> {
+        &lifetime
+    }
+
+    fn intern_parameter(
+        &self,
+        parameter: chalk_ir::ParameterData<Self>,
+    ) -> Self::InternedParameter {
+        Box::new(parameter)
+    }
+
+    fn parameter_data<'a>(
+        &self,
+        parameter: &'a Self::InternedParameter,
+    ) -> &'a chalk_ir::ParameterData<Self> {
+        &parameter
+    }
+
+    fn intern_goal(&self, goal: GoalData<Self>) -> Self::InternedGoal {
+        Box::new(goal)
+    }
+
+    fn goal_data<'a>(&self, goal: &'a Self::InternedGoal) -> &'a GoalData<Self> {
+        &goal
+    }
+
+    fn intern_goals<E>(
+        &self,
+        data: impl IntoIterator<Item = Result<chalk_ir::Goal<Self>, E>>,
+    ) -> Result<Self::InternedGoals, E> {
+        data.into_iter().collect::<Result<Vec<_>, _>>()
+    }
+
+    fn goals_data<'a>(&self, goals: &'a Self::InternedGoals) -> &'a [chalk_ir::Goal<Self>] {
+        goals
+    }
+
+    fn intern_substitution<E>(
+        &self,
+        data: impl IntoIterator<Item = Result<chalk_ir::Parameter<Self>, E>>,
+    ) -> Result<Self::InternedSubstitution, E> {
+        data.into_iter().collect::<Result<Vec<_>, _>>()
+    }
+
+    fn substitution_data<'a>(
+        &self,
+        substitution: &'a Self::InternedSubstitution,
+    ) -> &'a [Parameter<Self>] {
+        substitution
+    }
+
+    fn intern_program_clause(
+        &self,
+        data: chalk_ir::ProgramClauseData<Self>,
+    ) -> Self::InternedProgramClause {
+        Box::new(data)
+    }
+
+    fn program_clause_data<'a>(
+        &self,
+        clause: &'a Self::InternedProgramClause,
+    ) -> &'a chalk_ir::ProgramClauseData<Self> {
+        &clause
+    }
+
+    fn intern_program_clauses<E>(
+        &self,
+        data: impl IntoIterator<Item = Result<chalk_ir::ProgramClause<Self>, E>>,
+    ) -> Result<Self::InternedProgramClauses, E> {
+        data.into_iter().collect::<Result<Vec<_>, _>>()
+    }
+
+    fn program_clauses_data<'a>(
+        &self,
+        clauses: &'a Self::InternedProgramClauses,
+    ) -> &'a [chalk_ir::ProgramClause<Self>] {
+        clauses
+    }
+
+    fn intern_quantified_where_clauses<E>(
+        &self,
+        data: impl IntoIterator<Item = Result<chalk_ir::QuantifiedWhereClause<Self>, E>>,
+    ) -> Result<Self::InternedQuantifiedWhereClauses, E> {
+        data.into_iter().collect::<Result<Vec<_>, _>>()
+    }
+
+    fn quantified_where_clauses_data<'a>(
+        &self,
+        clauses: &'a Self::InternedQuantifiedWhereClauses,
+    ) -> &'a [chalk_ir::QuantifiedWhereClause<Self>] {
+        clauses
+    }
+
+    fn intern_parameter_kinds<E>(
+        &self,
+        data: impl IntoIterator<Item = Result<chalk_ir::ParameterKind<()>, E>>,
+    ) -> Result<Self::InternedParameterKinds, E> {
+        data.into_iter().collect::<Result<Vec<_>, _>>()
+    }
+
+    fn parameter_kinds_data<'a>(
+        &self,
+        parameter_kinds: &'a Self::InternedParameterKinds,
+    ) -> &'a [chalk_ir::ParameterKind<()>] {
+        parameter_kinds
+    }
+
+    fn intern_canonical_var_kinds<E>(
+        &self,
+        data: impl IntoIterator<Item = Result<chalk_ir::ParameterKind<chalk_ir::UniverseIndex>, E>>,
+    ) -> Result<Self::InternedCanonicalVarKinds, E> {
+        data.into_iter().collect::<Result<Vec<_>, _>>()
+    }
+
+    fn canonical_var_kinds_data<'a>(
+        &self,
+        canonical_var_kinds: &'a Self::InternedCanonicalVarKinds,
+    ) -> &'a [chalk_ir::ParameterKind<chalk_ir::UniverseIndex>] {
+        canonical_var_kinds
+    }
+}
+
+impl<'tcx> chalk_ir::interner::HasInterner for RustInterner<'tcx> {
+    type Interner = Self;
+}
+
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)]
+pub enum ChalkEnvironmentClause<'tcx> {
+    /// A normal rust `ty::Predicate` in the environment.
+    Predicate(ty::Predicate<'tcx>),
+    /// A special clause in the environment that gets lowered to
+    /// `chalk_ir::FromEnv::Ty`.
+    TypeFromEnv(Ty<'tcx>),
+}
+
+impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ChalkEnvironmentClause<'tcx>> {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
+        let v = self.iter().map(|t| t.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
+        folder.tcx().intern_chalk_environment_clause_list(&v)
+    }
+
+    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
+        self.iter().any(|t| t.visit_with(visitor))
+    }
+}
+/// We have to elaborate the environment of a chalk goal *before*
+/// canonicalization. This type wraps the predicate and the elaborated
+/// environment.
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)]
+pub struct ChalkEnvironmentAndGoal<'tcx> {
+    pub environment: &'tcx ty::List<ChalkEnvironmentClause<'tcx>>,
+    pub goal: ty::Predicate<'tcx>,
+}
+
+impl<'tcx> fmt::Display for ChalkEnvironmentAndGoal<'tcx> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "environment: {:?}, goal: {}", self.environment, self.goal)
+    }
+}
diff --git a/src/librustc_middle/traits/mod.rs b/src/librustc_middle/traits/mod.rs
index 3a05d577bfa..1254174a7a5 100644
--- a/src/librustc_middle/traits/mod.rs
+++ b/src/librustc_middle/traits/mod.rs
@@ -2,18 +2,20 @@
 //!
 //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/resolution.html
 
+mod chalk;
 pub mod query;
 pub mod select;
 pub mod specialization_graph;
 mod structural_impls;
 
+use crate::infer::canonical::Canonical;
 use crate::mir::interpret::ErrorHandled;
 use crate::ty::subst::SubstsRef;
 use crate::ty::{self, AdtKind, Ty, TyCtxt};
 
-use rustc_ast::ast;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
+use rustc_span::symbol::Symbol;
 use rustc_span::{Span, DUMMY_SP};
 use smallvec::SmallVec;
 
@@ -23,10 +25,17 @@ use std::rc::Rc;
 
 pub use self::select::{EvaluationCache, EvaluationResult, OverflowError, SelectionCache};
 
+pub type ChalkCanonicalGoal<'tcx> = Canonical<'tcx, ChalkEnvironmentAndGoal<'tcx>>;
+
 pub use self::ObligationCauseCode::*;
 pub use self::SelectionError::*;
 pub use self::Vtable::*;
 
+pub use self::chalk::{
+    ChalkEnvironmentAndGoal, ChalkEnvironmentClause, RustDefId as ChalkRustDefId,
+    RustInterner as ChalkRustInterner,
+};
+
 /// Depending on the stage of compilation, we want projection to be
 /// more or less conservative.
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, HashStable)]
@@ -198,14 +207,14 @@ pub enum ObligationCauseCode<'tcx> {
 
     /// Error derived when matching traits/impls; see ObligationCause for more details
     CompareImplMethodObligation {
-        item_name: ast::Name,
+        item_name: Symbol,
         impl_item_def_id: DefId,
         trait_item_def_id: DefId,
     },
 
     /// Error derived when matching traits/impls; see ObligationCause for more details
     CompareImplTypeObligation {
-        item_name: ast::Name,
+        item_name: Symbol,
         impl_item_def_id: DefId,
         trait_item_def_id: DefId,
     },
@@ -566,10 +575,10 @@ pub enum ObjectSafetyViolation {
     SupertraitSelf(SmallVec<[Span; 1]>),
 
     /// Method has something illegal.
-    Method(ast::Name, MethodViolationCode, Span),
+    Method(Symbol, MethodViolationCode, Span),
 
     /// Associated const.
-    AssocConst(ast::Name, Span),
+    AssocConst(Symbol, Span),
 }
 
 impl ObjectSafetyViolation {
diff --git a/src/librustc_middle/traits/specialization_graph.rs b/src/librustc_middle/traits/specialization_graph.rs
index bc743666e4a..4f02aaa96ac 100644
--- a/src/librustc_middle/traits/specialization_graph.rs
+++ b/src/librustc_middle/traits/specialization_graph.rs
@@ -1,11 +1,11 @@
 use crate::ich::{self, StableHashingContext};
 use crate::ty::fast_reject::SimplifiedType;
 use crate::ty::{self, TyCtxt};
-use rustc_ast::ast::Ident;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_errors::ErrorReported;
 use rustc_hir::def_id::{DefId, DefIdMap};
+use rustc_span::symbol::Ident;
 
 /// A per-trait graph of impls in specialization order. At the moment, this
 /// graph forms a tree rooted with the trait itself, with all other nodes
diff --git a/src/librustc_middle/ty/context.rs b/src/librustc_middle/ty/context.rs
index e43eb01ad96..86b740b8503 100644
--- a/src/librustc_middle/ty/context.rs
+++ b/src/librustc_middle/ty/context.rs
@@ -93,6 +93,8 @@ pub struct CtxtInterners<'tcx> {
     projs: InternedSet<'tcx, List<ProjectionKind>>,
     place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
     const_: InternedSet<'tcx, Const<'tcx>>,
+
+    chalk_environment_clause_list: InternedSet<'tcx, List<traits::ChalkEnvironmentClause<'tcx>>>,
 }
 
 impl<'tcx> CtxtInterners<'tcx> {
@@ -109,6 +111,8 @@ impl<'tcx> CtxtInterners<'tcx> {
             projs: Default::default(),
             place_elems: Default::default(),
             const_: Default::default(),
+
+            chalk_environment_clause_list: Default::default(),
         }
     }
 
@@ -376,7 +380,7 @@ pub struct TypeckTables<'tcx> {
 
     /// Records the reasons that we picked the kind of each closure;
     /// not all closures are present in the map.
-    closure_kind_origins: ItemLocalMap<(Span, ast::Name)>,
+    closure_kind_origins: ItemLocalMap<(Span, Symbol)>,
 
     /// For each fn, records the "liberated" types of its arguments
     /// and return type. Liberated means that all bound regions
@@ -621,11 +625,11 @@ impl<'tcx> TypeckTables<'tcx> {
         self.upvar_capture_map[&upvar_id]
     }
 
-    pub fn closure_kind_origins(&self) -> LocalTableInContext<'_, (Span, ast::Name)> {
+    pub fn closure_kind_origins(&self) -> LocalTableInContext<'_, (Span, Symbol)> {
         LocalTableInContext { hir_owner: self.hir_owner, data: &self.closure_kind_origins }
     }
 
-    pub fn closure_kind_origins_mut(&mut self) -> LocalTableInContextMut<'_, (Span, ast::Name)> {
+    pub fn closure_kind_origins_mut(&mut self) -> LocalTableInContextMut<'_, (Span, Symbol)> {
         LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.closure_kind_origins }
     }
 
@@ -941,10 +945,10 @@ pub struct GlobalCtxt<'tcx> {
     maybe_unused_extern_crates: Vec<(DefId, Span)>,
     /// A map of glob use to a set of names it actually imports. Currently only
     /// used in save-analysis.
-    glob_map: FxHashMap<LocalDefId, FxHashSet<ast::Name>>,
+    glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
     /// Extern prelude entries. The value is `true` if the entry was introduced
     /// via `extern crate` item and not `--extern` option or compiler built-in.
-    pub extern_prelude: FxHashMap<ast::Name, bool>,
+    pub extern_prelude: FxHashMap<Symbol, bool>,
 
     // Internal cache for metadata decoding. No need to track deps on this.
     pub rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
@@ -975,7 +979,7 @@ pub struct GlobalCtxt<'tcx> {
     allocation_interner: ShardedHashMap<&'tcx Allocation, ()>,
 
     /// Stores memory for globals (statics/consts).
-    pub alloc_map: Lock<interpret::AllocMap<'tcx>>,
+    pub(crate) alloc_map: Lock<interpret::AllocMap<'tcx>>,
 
     layout_interner: ShardedHashMap<&'tcx Layout, ()>,
 
@@ -1013,7 +1017,7 @@ impl<'tcx> TyCtxt<'tcx> {
         // Create an allocation that just contains these bytes.
         let alloc = interpret::Allocation::from_byte_aligned_bytes(bytes);
         let alloc = self.intern_const_alloc(alloc);
-        self.alloc_map.lock().create_memory_alloc(alloc)
+        self.create_memory_alloc(alloc)
     }
 
     pub fn intern_stability(self, stab: attr::Stability) -> &'tcx attr::Stability {
@@ -1997,6 +2001,14 @@ impl<'tcx> Borrow<Const<'tcx>> for Interned<'tcx, Const<'tcx>> {
     }
 }
 
+impl<'tcx> Borrow<[traits::ChalkEnvironmentClause<'tcx>]>
+    for Interned<'tcx, List<traits::ChalkEnvironmentClause<'tcx>>>
+{
+    fn borrow<'a>(&'a self) -> &'a [traits::ChalkEnvironmentClause<'tcx>] {
+        &self.0[..]
+    }
+}
+
 macro_rules! direct_interners {
     ($($name:ident: $method:ident($ty:ty)),+) => {
         $(impl<'tcx> PartialEq for Interned<'tcx, $ty> {
@@ -2044,7 +2056,9 @@ slice_interners!(
     existential_predicates: _intern_existential_predicates(ExistentialPredicate<'tcx>),
     predicates: _intern_predicates(Predicate<'tcx>),
     projs: _intern_projs(ProjectionKind),
-    place_elems: _intern_place_elems(PlaceElem<'tcx>)
+    place_elems: _intern_place_elems(PlaceElem<'tcx>),
+    chalk_environment_clause_list:
+        _intern_chalk_environment_clause_list(traits::ChalkEnvironmentClause<'tcx>)
 );
 
 impl<'tcx> TyCtxt<'tcx> {
@@ -2430,6 +2444,13 @@ impl<'tcx> TyCtxt<'tcx> {
         if ts.is_empty() { List::empty() } else { self._intern_canonical_var_infos(ts) }
     }
 
+    pub fn intern_chalk_environment_clause_list(
+        self,
+        ts: &[traits::ChalkEnvironmentClause<'tcx>],
+    ) -> &'tcx List<traits::ChalkEnvironmentClause<'tcx>> {
+        if ts.is_empty() { List::empty() } else { self._intern_chalk_environment_clause_list(ts) }
+    }
+
     pub fn mk_fn_sig<I>(
         self,
         inputs: I,
@@ -2487,6 +2508,18 @@ impl<'tcx> TyCtxt<'tcx> {
         self.mk_substs(iter::once(self_ty.into()).chain(rest.iter().cloned()))
     }
 
+    pub fn mk_chalk_environment_clause_list<
+        I: InternAs<
+            [traits::ChalkEnvironmentClause<'tcx>],
+            &'tcx List<traits::ChalkEnvironmentClause<'tcx>>,
+        >,
+    >(
+        self,
+        iter: I,
+    ) -> I::Output {
+        iter.intern_with(|xs| self.intern_chalk_environment_clause_list(xs))
+    }
+
     /// Walks upwards from `id` to find a node which might change lint levels with attributes.
     /// It stops at `bound` and just returns it if reached.
     pub fn maybe_lint_level_root_bounded(self, mut id: HirId, bound: HirId) -> HirId {
diff --git a/src/librustc_middle/ty/layout.rs b/src/librustc_middle/ty/layout.rs
index ade89ab39d4..7c4e4d095bc 100644
--- a/src/librustc_middle/ty/layout.rs
+++ b/src/librustc_middle/ty/layout.rs
@@ -4,13 +4,14 @@ use crate::mir::{GeneratorLayout, GeneratorSavedLocal};
 use crate::ty::subst::Subst;
 use crate::ty::{self, subst::SubstsRef, ReprOptions, Ty, TyCtxt, TypeFoldable};
 
-use rustc_ast::ast::{self, Ident, IntTy, UintTy};
+use rustc_ast::ast::{self, IntTy, UintTy};
 use rustc_attr as attr;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_hir as hir;
 use rustc_index::bit_set::BitSet;
 use rustc_index::vec::{Idx, IndexVec};
 use rustc_session::{DataTypeKind, FieldInfo, SizeKind, VariantInfo};
+use rustc_span::symbol::{Ident, Symbol};
 use rustc_span::DUMMY_SP;
 use rustc_target::abi::call::{
     ArgAbi, ArgAttribute, ArgAttributes, Conv, FnAbi, PassMode, Reg, RegKind,
@@ -1628,9 +1629,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
         let adt_kind = adt_def.adt_kind();
         let adt_packed = adt_def.repr.pack.is_some();
 
-        let build_variant_info = |n: Option<Ident>,
-                                  flds: &[ast::Name],
-                                  layout: TyAndLayout<'tcx>| {
+        let build_variant_info = |n: Option<Ident>, flds: &[Symbol], layout: TyAndLayout<'tcx>| {
             let mut min_size = Size::ZERO;
             let field_info: Vec<_> = flds
                 .iter()
diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs
index 8bb9934789a..02fe7adcd07 100644
--- a/src/librustc_middle/ty/mod.rs
+++ b/src/librustc_middle/ty/mod.rs
@@ -17,7 +17,7 @@ use crate::traits::{self, Reveal};
 use crate::ty;
 use crate::ty::subst::{InternalSubsts, Subst, SubstsRef};
 use crate::ty::util::{Discr, IntTypeExt};
-use rustc_ast::ast::{self, Ident, Name};
+use rustc_ast::ast;
 use rustc_ast::node_id::{NodeId, NodeMap, NodeSet};
 use rustc_attr as attr;
 use rustc_data_structures::captures::Captures;
@@ -38,7 +38,7 @@ use rustc_macros::HashStable;
 use rustc_serialize::{self, Encodable, Encoder};
 use rustc_session::DataTypeKind;
 use rustc_span::hygiene::ExpnId;
-use rustc_span::symbol::{kw, sym, Symbol};
+use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::Span;
 use rustc_target::abi::{Align, VariantIdx};
 
@@ -128,7 +128,7 @@ pub struct ResolverOutputs {
     pub glob_map: GlobMap,
     /// Extern prelude entries. The value is `true` if the entry was introduced
     /// via `extern crate` item and not `--extern` option or compiler built-in.
-    pub extern_prelude: FxHashMap<Name, bool>,
+    pub extern_prelude: FxHashMap<Symbol, bool>,
 }
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable)]
diff --git a/src/librustc_middle/ty/print/pretty.rs b/src/librustc_middle/ty/print/pretty.rs
index 2d2704fc2bd..2684492a406 100644
--- a/src/librustc_middle/ty/print/pretty.rs
+++ b/src/librustc_middle/ty/print/pretty.rs
@@ -12,7 +12,7 @@ use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, DefKind, Namespace};
 use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
-use rustc_span::symbol::{kw, Symbol};
+use rustc_span::symbol::{kw, Ident, Symbol};
 use rustc_target::abi::{Integer, Size};
 use rustc_target::spec::abi::Abi;
 
@@ -956,9 +956,8 @@ pub trait PrettyPrinter<'tcx>:
             ) => {
                 let byte_str = self
                     .tcx()
-                    .alloc_map
-                    .lock()
-                    .unwrap_memory(ptr.alloc_id)
+                    .global_alloc(ptr.alloc_id)
+                    .unwrap_memory()
                     .get_bytes(&self.tcx(), ptr, Size::from_bytes(*data))
                     .unwrap();
                 p!(pretty_print_byte_str(byte_str));
@@ -1021,10 +1020,7 @@ pub trait PrettyPrinter<'tcx>:
                 )?;
             }
             (Scalar::Ptr(ptr), ty::FnPtr(_)) => {
-                let instance = {
-                    let alloc_map = self.tcx().alloc_map.lock();
-                    alloc_map.unwrap_fn(ptr.alloc_id)
-                };
+                let instance = self.tcx().global_alloc(ptr.alloc_id).unwrap_fn();
                 self = self.typed_value(
                     |this| this.print_value_path(instance.def_id(), instance.substs),
                     |this| this.print_type(ty),
@@ -1456,7 +1452,7 @@ impl<F: fmt::Write> Printer<'tcx> for FmtPrinter<'_, 'tcx, F> {
             if !self.empty_path {
                 write!(self, "::")?;
             }
-            if ast::Ident::from_str(&name).is_raw_guess() {
+            if Ident::from_str(&name).is_raw_guess() {
                 write!(self, "r#")?;
             }
             write!(self, "{}", name)?;
diff --git a/src/librustc_middle/ty/query/on_disk_cache.rs b/src/librustc_middle/ty/query/on_disk_cache.rs
index 760fdbe8522..71c2c24cc0a 100644
--- a/src/librustc_middle/ty/query/on_disk_cache.rs
+++ b/src/librustc_middle/ty/query/on_disk_cache.rs
@@ -4,7 +4,6 @@ use crate::mir::{self, interpret};
 use crate::ty::codec::{self as ty_codec, TyDecoder, TyEncoder};
 use crate::ty::context::TyCtxt;
 use crate::ty::{self, Ty};
-use rustc_ast::ast::Ident;
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::{HashMapExt, Lock, Lrc, Once};
@@ -20,6 +19,7 @@ use rustc_serialize::{
 use rustc_session::{CrateDisambiguator, Session};
 use rustc_span::hygiene::{ExpnId, SyntaxContext};
 use rustc_span::source_map::{SourceMap, StableSourceFileId};
+use rustc_span::symbol::Ident;
 use rustc_span::CachingSourceMapView;
 use rustc_span::{BytePos, SourceFile, Span, DUMMY_SP};
 use std::mem;
diff --git a/src/librustc_middle/ty/relate.rs b/src/librustc_middle/ty/relate.rs
index faa74f81e81..9c198dd556a 100644
--- a/src/librustc_middle/ty/relate.rs
+++ b/src/librustc_middle/ty/relate.rs
@@ -549,9 +549,8 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
                     if a_val == b_val {
                         Ok(ConstValue::Scalar(a_val))
                     } else if let ty::FnPtr(_) = a.ty.kind {
-                        let alloc_map = tcx.alloc_map.lock();
-                        let a_instance = alloc_map.unwrap_fn(a_val.assert_ptr().alloc_id);
-                        let b_instance = alloc_map.unwrap_fn(b_val.assert_ptr().alloc_id);
+                        let a_instance = tcx.global_alloc(a_val.assert_ptr().alloc_id).unwrap_fn();
+                        let b_instance = tcx.global_alloc(b_val.assert_ptr().alloc_id).unwrap_fn();
                         if a_instance == b_instance {
                             Ok(ConstValue::Scalar(a_val))
                         } else {
diff --git a/src/librustc_middle/ty/sty.rs b/src/librustc_middle/ty/sty.rs
index ac5477edcc3..a6cf3b7e2ee 100644
--- a/src/librustc_middle/ty/sty.rs
+++ b/src/librustc_middle/ty/sty.rs
@@ -16,14 +16,14 @@ use crate::ty::{
 };
 use crate::ty::{List, ParamEnv, ParamEnvAnd, TyS};
 use polonius_engine::Atom;
-use rustc_ast::ast::{self, Ident};
+use rustc_ast::ast;
 use rustc_data_structures::captures::Captures;
 use rustc_errors::ErrorReported;
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_index::vec::Idx;
 use rustc_macros::HashStable;
-use rustc_span::symbol::{kw, Symbol};
+use rustc_span::symbol::{kw, Ident, Symbol};
 use rustc_target::abi::{Size, VariantIdx};
 use rustc_target::spec::abi;
 use std::borrow::Cow;
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 457f0f8444b..d3ab7df817b 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -1,6 +1,5 @@
 //! This query borrow-checks the MIR to (further) ensure it is not broken.
 
-use rustc_ast::ast::Name;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::graph::dominators::Dominators;
 use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorReported};
@@ -22,7 +21,7 @@ use rustc_middle::mir::{Terminator, TerminatorKind};
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::{self, RegionVid, TyCtxt};
 use rustc_session::lint::builtin::{MUTABLE_BORROW_RESERVATION_CONFLICT, UNUSED_MUT};
-use rustc_span::{Span, DUMMY_SP};
+use rustc_span::{Span, Symbol, DUMMY_SP};
 
 use either::Either;
 use smallvec::SmallVec;
@@ -77,7 +76,7 @@ crate use region_infer::RegionInferenceContext;
 // FIXME(eddyb) perhaps move this somewhere more centrally.
 #[derive(Debug)]
 crate struct Upvar {
-    name: Name,
+    name: Symbol,
 
     var_hir_id: HirId,
 
@@ -534,7 +533,7 @@ crate struct MirBorrowckCtxt<'cx, 'tcx> {
     upvars: Vec<Upvar>,
 
     /// Names of local (user) variables (extracted from `var_debug_info`).
-    local_names: IndexVec<Local, Option<Name>>,
+    local_names: IndexVec<Local, Option<Symbol>>,
 
     /// Record the region names generated for each region in the given
     /// MIR def so that we can reuse them later in help/error messages.
diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs
index 2f635b4a1c1..b6c635fb22a 100644
--- a/src/librustc_mir/const_eval/eval_queries.rs
+++ b/src/librustc_mir/const_eval/eval_queries.rs
@@ -130,7 +130,7 @@ pub(super) fn op_to_const<'tcx>(
 
     let to_const_value = |mplace: MPlaceTy<'_>| match mplace.ptr {
         Scalar::Ptr(ptr) => {
-            let alloc = ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id);
+            let alloc = ecx.tcx.global_alloc(ptr.alloc_id).unwrap_memory();
             ConstValue::ByRef { alloc, offset: ptr.offset }
         }
         Scalar::Raw { data, .. } => {
@@ -155,7 +155,7 @@ pub(super) fn op_to_const<'tcx>(
             Immediate::ScalarPair(a, b) => {
                 let (data, start) = match a.not_undef().unwrap() {
                     Scalar::Ptr(ptr) => {
-                        (ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id), ptr.offset.bytes())
+                        (ecx.tcx.global_alloc(ptr.alloc_id).unwrap_memory(), ptr.offset.bytes())
                     }
                     Scalar::Raw { .. } => (
                         ecx.tcx
@@ -203,7 +203,7 @@ fn validate_and_turn_into_const<'tcx>(
         if is_static || cid.promoted.is_some() {
             let ptr = mplace.ptr.assert_ptr();
             Ok(ConstValue::ByRef {
-                alloc: ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id),
+                alloc: ecx.tcx.global_alloc(ptr.alloc_id).unwrap_memory(),
                 offset: ptr.offset,
             })
         } else {
diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs
index 8bc0e2ee6a4..1c44101595d 100644
--- a/src/librustc_mir/interpret/intern.rs
+++ b/src/librustc_mir/interpret/intern.rs
@@ -91,7 +91,7 @@ fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>>(
             // If the pointer is dangling (neither in local nor global memory), we leave it
             // to validation to error. The `delay_span_bug` ensures that we don't forget such
             // a check in validation.
-            if tcx.alloc_map.lock().get(alloc_id).is_none() {
+            if tcx.get_global_alloc(alloc_id).is_none() {
                 tcx.sess.delay_span_bug(ecx.tcx.span, "tried to intern dangling pointer");
             }
             // treat dangling pointers like other statics
@@ -134,7 +134,7 @@ fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>>(
     // link the alloc id to the actual allocation
     let alloc = tcx.intern_const_alloc(alloc);
     leftover_allocations.extend(alloc.relocations().iter().map(|&(_, ((), reloc))| reloc));
-    tcx.alloc_map.lock().set_alloc_id_memory(alloc_id, alloc);
+    tcx.set_alloc_id_memory(alloc_id, alloc);
     Ok(None)
 }
 
@@ -389,7 +389,7 @@ where
                 }
             }
             let alloc = tcx.intern_const_alloc(alloc);
-            tcx.alloc_map.lock().set_alloc_id_memory(alloc_id, alloc);
+            tcx.set_alloc_id_memory(alloc_id, alloc);
             for &(_, ((), reloc)) in alloc.relocations().iter() {
                 if leftover_allocations.insert(reloc) {
                     todo.push(reloc);
@@ -398,7 +398,7 @@ where
         } else if ecx.memory.dead_alloc_map.contains_key(&alloc_id) {
             // dangling pointer
             throw_ub_format!("encountered dangling pointer in final constant")
-        } else if ecx.tcx.alloc_map.lock().get(alloc_id).is_none() {
+        } else if ecx.tcx.get_global_alloc(alloc_id).is_none() {
             // We have hit an `AllocId` that is neither in local or global memory and isn't marked
             // as dangling by local memory.
             span_bug!(ecx.tcx.span, "encountered unknown alloc id {:?}", alloc_id);
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index 39e428cee1d..61c365644c7 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -153,10 +153,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
         fn_val: FnVal<'tcx, M::ExtraFnVal>,
     ) -> Pointer<M::PointerTag> {
         let id = match fn_val {
-            FnVal::Instance(instance) => self.tcx.alloc_map.lock().create_fn_alloc(instance),
+            FnVal::Instance(instance) => self.tcx.create_fn_alloc(instance),
             FnVal::Other(extra) => {
                 // FIXME(RalfJung): Should we have a cache here?
-                let id = self.tcx.alloc_map.lock().reserve();
+                let id = self.tcx.reserve_alloc_id();
                 let old = self.extra_fn_ptr_map.insert(id, extra);
                 assert!(old.is_none());
                 id
@@ -189,7 +189,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
         alloc: Allocation,
         kind: MemoryKind<M::MemoryKind>,
     ) -> Pointer<M::PointerTag> {
-        let id = self.tcx.alloc_map.lock().reserve();
+        let id = self.tcx.reserve_alloc_id();
         debug_assert_ne!(
             Some(kind),
             M::GLOBAL_KIND.map(MemoryKind::Machine),
@@ -260,7 +260,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
             Some(alloc) => alloc,
             None => {
                 // Deallocating global memory -- always an error
-                return Err(match self.tcx.alloc_map.lock().get(ptr.alloc_id) {
+                return Err(match self.tcx.get_global_alloc(ptr.alloc_id) {
                     Some(GlobalAlloc::Function(..)) => err_ub_format!("deallocating a function"),
                     Some(GlobalAlloc::Static(..) | GlobalAlloc::Memory(..)) => {
                         err_ub_format!("deallocating static memory")
@@ -429,8 +429,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
         id: AllocId,
         is_write: bool,
     ) -> InterpResult<'tcx, Cow<'tcx, Allocation<M::PointerTag, M::AllocExtra>>> {
-        let alloc = tcx.alloc_map.lock().get(id);
-        let (alloc, def_id) = match alloc {
+        let (alloc, def_id) = match tcx.get_global_alloc(id) {
             Some(GlobalAlloc::Memory(mem)) => {
                 // Memory of a constant or promoted or anonymous memory referenced by a static.
                 (mem, None)
@@ -468,7 +467,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
                     })?;
                 // Make sure we use the ID of the resolved memory, not the lazy one!
                 let id = raw_const.alloc_id;
-                let allocation = tcx.alloc_map.lock().unwrap_memory(id);
+                let allocation = tcx.global_alloc(id).unwrap_memory();
 
                 (allocation, Some(def_id))
             }
@@ -591,8 +590,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
         // # Statics
         // Can't do this in the match argument, we may get cycle errors since the lock would
         // be held throughout the match.
-        let alloc = self.tcx.alloc_map.lock().get(id);
-        match alloc {
+        match self.tcx.get_global_alloc(id) {
             Some(GlobalAlloc::Static(did)) => {
                 // Use size and align of the type.
                 let ty = self.tcx.type_of(did);
@@ -627,7 +625,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
         if let Some(extra) = self.extra_fn_ptr_map.get(&id) {
             Some(FnVal::Other(*extra))
         } else {
-            match self.tcx.alloc_map.lock().get(id) {
+            match self.tcx.get_global_alloc(id) {
                 Some(GlobalAlloc::Function(instance)) => Some(FnVal::Instance(instance)),
                 _ => None,
             }
@@ -695,7 +693,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
                 }
                 None => {
                     // global alloc
-                    match self.tcx.alloc_map.lock().get(id) {
+                    match self.tcx.get_global_alloc(id) {
                         Some(GlobalAlloc::Memory(alloc)) => {
                             eprint!(" (unchanged global, ");
                             write_allocation_track_relocs(self.tcx, &mut allocs_to_print, alloc);
diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index 81009fd7b98..a3caa2048a1 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -549,7 +549,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         let layout = from_known_layout(self.tcx, layout, || self.layout_of(val.ty))?;
         let op = match val_val {
             ConstValue::ByRef { alloc, offset } => {
-                let id = self.tcx.alloc_map.lock().create_memory_alloc(alloc);
+                let id = self.tcx.create_memory_alloc(alloc);
                 // We rely on mutability being set correctly in that allocation to prevent writes
                 // where none should happen.
                 let ptr = self.tag_global_base_pointer(Pointer::new(id, offset));
@@ -560,7 +560,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 // We rely on mutability being set correctly in `data` to prevent writes
                 // where none should happen.
                 let ptr = Pointer::new(
-                    self.tcx.alloc_map.lock().create_memory_alloc(data),
+                    self.tcx.create_memory_alloc(data),
                     Size::from_bytes(start), // offset: `start`
                 );
                 Operand::Immediate(Immediate::new_slice(
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 2e8b1e64aed..6dadb8e4c67 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -1101,7 +1101,7 @@ where
         raw: RawConst<'tcx>,
     ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
         // This must be an allocation in `tcx`
-        assert!(self.tcx.alloc_map.lock().get(raw.alloc_id).is_some());
+        let _ = self.tcx.global_alloc(raw.alloc_id);
         let ptr = self.tag_global_base_pointer(Pointer::from(raw.alloc_id));
         let layout = self.layout_of(raw.ty)?;
         Ok(MPlaceTy::from_aligned_ptr(ptr, layout))
diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index e563cf78f8a..4f90f83b735 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -416,7 +416,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
             if let Some(ptr) = ptr {
                 // not a ZST
                 // Skip validation entirely for some external statics
-                let alloc_kind = self.ecx.tcx.alloc_map.lock().get(ptr.alloc_id);
+                let alloc_kind = self.ecx.tcx.get_global_alloc(ptr.alloc_id);
                 if let Some(GlobalAlloc::Static(did)) = alloc_kind {
                     // See const_eval::machine::MemoryExtra::can_access_statics for why
                     // this check is so important.
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index 3d798254735..4648100e3b7 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -1136,16 +1136,15 @@ fn create_mono_items_for_default_impls<'tcx>(
 
 /// Scans the miri alloc in order to find function calls, closures, and drop-glue.
 fn collect_miri<'tcx>(tcx: TyCtxt<'tcx>, alloc_id: AllocId, output: &mut Vec<MonoItem<'tcx>>) {
-    let alloc_kind = tcx.alloc_map.lock().get(alloc_id);
-    match alloc_kind {
-        Some(GlobalAlloc::Static(def_id)) => {
+    match tcx.global_alloc(alloc_id) {
+        GlobalAlloc::Static(def_id) => {
             let instance = Instance::mono(tcx, def_id);
             if should_monomorphize_locally(tcx, &instance) {
                 trace!("collecting static {:?}", def_id);
                 output.push(MonoItem::Static(def_id));
             }
         }
-        Some(GlobalAlloc::Memory(alloc)) => {
+        GlobalAlloc::Memory(alloc) => {
             trace!("collecting {:?} with {:#?}", alloc_id, alloc);
             for &((), inner) in alloc.relocations().values() {
                 rustc_data_structures::stack::ensure_sufficient_stack(|| {
@@ -1153,13 +1152,12 @@ fn collect_miri<'tcx>(tcx: TyCtxt<'tcx>, alloc_id: AllocId, output: &mut Vec<Mon
                 });
             }
         }
-        Some(GlobalAlloc::Function(fn_instance)) => {
+        GlobalAlloc::Function(fn_instance) => {
             if should_monomorphize_locally(tcx, &fn_instance) {
                 trace!("collecting {:?} with {:#?}", alloc_id, fn_instance);
                 output.push(create_fn_mono_item(fn_instance));
             }
         }
-        None => bug!("alloc id without corresponding allocation: {}", alloc_id),
     }
 }
 
diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs
index 02356a43699..220691c1570 100644
--- a/src/librustc_mir/transform/mod.rs
+++ b/src/librustc_mir/transform/mod.rs
@@ -1,6 +1,5 @@
 use crate::{shim, util};
 use required_consts::RequiredConstsVisitor;
-use rustc_ast::ast;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
 use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
@@ -11,7 +10,7 @@ use rustc_middle::mir::{traversal, Body, ConstQualifs, MirPhase, Promoted};
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::steal::Steal;
 use rustc_middle::ty::{InstanceDef, TyCtxt, TypeFoldable};
-use rustc_span::Span;
+use rustc_span::{Span, Symbol};
 use std::borrow::Cow;
 
 pub mod add_call_guards;
@@ -78,7 +77,7 @@ fn mir_keys(tcx: TyCtxt<'_>, krate: CrateNum) -> FxHashSet<LocalDefId> {
         fn visit_variant_data(
             &mut self,
             v: &'tcx hir::VariantData<'tcx>,
-            _: ast::Name,
+            _: Symbol,
             _: &'tcx hir::Generics<'tcx>,
             _: hir::HirId,
             _: Span,
diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs
index f3f45c0037d..ff386cb2183 100644
--- a/src/librustc_mir/util/pretty.rs
+++ b/src/librustc_mir/util/pretty.rs
@@ -588,8 +588,7 @@ pub fn write_allocations<'tcx>(
                 write_allocation(tcx, alloc, w)
             };
         write!(w, "\n{}", id)?;
-        let alloc = tcx.alloc_map.lock().get(id);
-        match alloc {
+        match tcx.get_global_alloc(id) {
             // This can't really happen unless there are bugs, but it doesn't cost us anything to
             // gracefully handle it and allow buggy rustc to be debugged via allocation printing.
             None => write!(w, " (deallocated)")?,
diff --git a/src/librustc_mir_build/build/matches/mod.rs b/src/librustc_mir_build/build/matches/mod.rs
index f14de38a3f9..43e9f305245 100644
--- a/src/librustc_mir_build/build/matches/mod.rs
+++ b/src/librustc_mir_build/build/matches/mod.rs
@@ -10,7 +10,6 @@ use crate::build::ForGuard::{self, OutsideGuard, RefWithinGuard};
 use crate::build::{BlockAnd, BlockAndExtension, Builder};
 use crate::build::{GuardFrame, GuardFrameLocal, LocalsForNode};
 use crate::hair::{self, *};
-use rustc_ast::ast::Name;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir::HirId;
 use rustc_index::bit_set::BitSet;
@@ -18,6 +17,7 @@ use rustc_middle::middle::region;
 use rustc_middle::mir::*;
 use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty};
 use rustc_span::Span;
+use rustc_span::symbol::Symbol;
 use rustc_target::abi::VariantIdx;
 use smallvec::{smallvec, SmallVec};
 
@@ -570,7 +570,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         f: &mut impl FnMut(
             &mut Self,
             Mutability,
-            Name,
+            Symbol,
             BindingMode,
             HirId,
             Span,
@@ -737,7 +737,7 @@ fn traverse_candidate<'pat, 'tcx: 'pat, C, T, I>(
 struct Binding<'tcx> {
     span: Span,
     source: Place<'tcx>,
-    name: Name,
+    name: Symbol,
     var_id: HirId,
     var_ty: Ty<'tcx>,
     mutability: Mutability,
@@ -1924,7 +1924,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         source_info: SourceInfo,
         visibility_scope: SourceScope,
         mutability: Mutability,
-        name: Name,
+        name: Symbol,
         mode: BindingMode,
         var_id: HirId,
         var_ty: Ty<'tcx>,
diff --git a/src/librustc_mir_build/hair/cx/expr.rs b/src/librustc_mir_build/hair/cx/expr.rs
index 0ef6d24d07b..8d572465d62 100644
--- a/src/librustc_mir_build/hair/cx/expr.rs
+++ b/src/librustc_mir_build/hair/cx/expr.rs
@@ -740,7 +740,7 @@ fn convert_path_expr<'a, 'tcx>(
         // a constant reference (or constant raw pointer for `static mut`) in MIR
         Res::Def(DefKind::Static, id) => {
             let ty = cx.tcx.static_ptr_ty(id);
-            let ptr = cx.tcx.alloc_map.lock().create_static_alloc(id);
+            let ptr = cx.tcx.create_static_alloc(id);
             let temp_lifetime = cx.region_scope_tree.temporary_scope(expr.hir_id.local_id);
             ExprKind::Deref {
                 arg: Expr {
diff --git a/src/librustc_mir_build/hair/pattern/_match.rs b/src/librustc_mir_build/hair/pattern/_match.rs
index cdafb63f1eb..f6941d3293b 100644
--- a/src/librustc_mir_build/hair/pattern/_match.rs
+++ b/src/librustc_mir_build/hair/pattern/_match.rs
@@ -286,7 +286,7 @@ impl<'tcx> LiteralExpander<'tcx> {
             (ConstValue::Scalar(p), x, y) if x == y => {
                 match p {
                     Scalar::Ptr(p) => {
-                        let alloc = self.tcx.alloc_map.lock().unwrap_memory(p.alloc_id);
+                        let alloc = self.tcx.global_alloc(p.alloc_id).unwrap_memory();
                         ConstValue::ByRef { alloc, offset: p.offset }
                     }
                     Scalar::Raw { .. } => {
@@ -305,7 +305,7 @@ impl<'tcx> LiteralExpander<'tcx> {
             (ConstValue::Scalar(Scalar::Ptr(p)), ty::Array(t, n), ty::Slice(u)) => {
                 assert_eq!(t, u);
                 ConstValue::Slice {
-                    data: self.tcx.alloc_map.lock().unwrap_memory(p.alloc_id),
+                    data: self.tcx.global_alloc(p.alloc_id).unwrap_memory(),
                     start: p.offset.bytes().try_into().unwrap(),
                     end: n.eval_usize(self.tcx, ty::ParamEnv::empty()).try_into().unwrap(),
                 }
diff --git a/src/librustc_mir_build/hair/pattern/mod.rs b/src/librustc_mir_build/hair/pattern/mod.rs
index bd75f11fb8f..f38471da94e 100644
--- a/src/librustc_mir_build/hair/pattern/mod.rs
+++ b/src/librustc_mir_build/hair/pattern/mod.rs
@@ -24,7 +24,7 @@ use rustc_middle::ty::{self, AdtDef, DefIdTree, Region, Ty, TyCtxt, UserType};
 use rustc_middle::ty::{
     CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations,
 };
-use rustc_span::{Span, DUMMY_SP};
+use rustc_span::{Span, Symbol, DUMMY_SP};
 use rustc_target::abi::VariantIdx;
 
 use std::cmp::Ordering;
@@ -128,7 +128,7 @@ crate enum PatKind<'tcx> {
     /// `x`, `ref x`, `x @ P`, etc.
     Binding {
         mutability: Mutability,
-        name: ast::Name,
+        name: Symbol,
         mode: BindingMode,
         var: hir::HirId,
         ty: Ty<'tcx>,
@@ -932,7 +932,7 @@ macro_rules! CloneImpls {
 }
 
 CloneImpls! { <'tcx>
-    Span, Field, Mutability, ast::Name, hir::HirId, usize, ty::Const<'tcx>,
+    Span, Field, Mutability, Symbol, hir::HirId, usize, ty::Const<'tcx>,
     Region<'tcx>, Ty<'tcx>, BindingMode, &'tcx AdtDef,
     SubstsRef<'tcx>, &'tcx GenericArg<'tcx>, UserType<'tcx>,
     UserTypeProjection, PatTyProj<'tcx>
diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs
index fe129f2c3a8..437d0ffa119 100644
--- a/src/librustc_parse/parser/diagnostics.rs
+++ b/src/librustc_parse/parser/diagnostics.rs
@@ -1,9 +1,7 @@
 use super::ty::AllowPlus;
 use super::{BlockMode, Parser, PathStyle, SemiColonMode, SeqSep, TokenExpectType, TokenType};
 
-use rustc_ast::ast::{
-    self, BinOpKind, BindingMode, BlockCheckMode, Expr, ExprKind, Ident, Item, Param,
-};
+use rustc_ast::ast::{self, BinOpKind, BindingMode, BlockCheckMode, Expr, ExprKind, Item, Param};
 use rustc_ast::ast::{AttrVec, ItemKind, Mutability, Pat, PatKind, PathSegment, QSelf, Ty, TyKind};
 use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Lit, LitKind, TokenKind};
@@ -13,7 +11,7 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{pluralize, struct_span_err};
 use rustc_errors::{Applicability, DiagnosticBuilder, Handler, PResult};
 use rustc_span::source_map::Spanned;
-use rustc_span::symbol::kw;
+use rustc_span::symbol::{kw, Ident};
 use rustc_span::{MultiSpan, Span, SpanSnippetError, DUMMY_SP};
 
 use log::{debug, trace};
diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs
index b3bb72554e9..ca497a3b06f 100644
--- a/src/librustc_parse/parser/expr.rs
+++ b/src/librustc_parse/parser/expr.rs
@@ -4,7 +4,7 @@ use super::{BlockMode, Parser, PathStyle, Restrictions, TokenType};
 use super::{SemiColonMode, SeqSep, TokenExpectType};
 use crate::maybe_recover_from_interpolated_ty_qpath;
 
-use rustc_ast::ast::{self, AttrStyle, AttrVec, CaptureBy, Field, Ident, Lit, UnOp, DUMMY_NODE_ID};
+use rustc_ast::ast::{self, AttrStyle, AttrVec, CaptureBy, Field, Lit, UnOp, DUMMY_NODE_ID};
 use rustc_ast::ast::{AnonConst, BinOp, BinOpKind, FnDecl, FnRetTy, MacCall, Param, Ty, TyKind};
 use rustc_ast::ast::{Arm, Async, BlockCheckMode, Expr, ExprKind, Label, Movability, RangeLimits};
 use rustc_ast::ptr::P;
@@ -15,7 +15,7 @@ use rustc_ast::util::parser::{prec_let_scrutinee_needs_par, AssocOp, Fixity};
 use rustc_ast_pretty::pprust;
 use rustc_errors::{Applicability, DiagnosticBuilder, PResult};
 use rustc_span::source_map::{self, Span, Spanned};
-use rustc_span::symbol::{kw, sym, Symbol};
+use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use std::mem;
 
 /// Possibly accepts an `token::Interpolated` expression (a pre-parsed expression
diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs
index 7fb814973e2..4fe0453e9c8 100644
--- a/src/librustc_parse/parser/item.rs
+++ b/src/librustc_parse/parser/item.rs
@@ -4,7 +4,7 @@ use super::{FollowedByType, Parser, PathStyle};
 
 use crate::maybe_whole;
 
-use rustc_ast::ast::{self, AttrStyle, AttrVec, Attribute, Ident, DUMMY_NODE_ID};
+use rustc_ast::ast::{self, AttrStyle, AttrVec, Attribute, DUMMY_NODE_ID};
 use rustc_ast::ast::{AssocItem, AssocItemKind, ForeignItemKind, Item, ItemKind, Mod};
 use rustc_ast::ast::{Async, Const, Defaultness, IsAuto, Mutability, Unsafe, UseTree, UseTreeKind};
 use rustc_ast::ast::{BindingMode, Block, FnDecl, FnSig, Param, SelfKind};
@@ -18,7 +18,7 @@ use rustc_ast_pretty::pprust;
 use rustc_errors::{struct_span_err, Applicability, PResult, StashKey};
 use rustc_span::edition::Edition;
 use rustc_span::source_map::{self, Span};
-use rustc_span::symbol::{kw, sym, Symbol};
+use rustc_span::symbol::{kw, sym, Ident, Symbol};
 
 use log::debug;
 use std::convert::TryFrom;
@@ -804,7 +804,7 @@ impl<'a> Parser<'a> {
         if self.eat_keyword(kw::As) { self.parse_ident_or_underscore().map(Some) } else { Ok(None) }
     }
 
-    fn parse_ident_or_underscore(&mut self) -> PResult<'a, ast::Ident> {
+    fn parse_ident_or_underscore(&mut self) -> PResult<'a, Ident> {
         match self.token.ident() {
             Some((ident @ Ident { name: kw::Underscore, .. }, false)) => {
                 self.bump();
@@ -834,7 +834,7 @@ impl<'a> Parser<'a> {
         Ok((item_name, ItemKind::ExternCrate(orig_name)))
     }
 
-    fn parse_crate_name_with_dashes(&mut self) -> PResult<'a, ast::Ident> {
+    fn parse_crate_name_with_dashes(&mut self) -> PResult<'a, Ident> {
         let error_msg = "crate name using dashes are not valid in `extern crate` statements";
         let suggestion_msg = "if the original crate name uses dashes you need to use underscores \
                               in the code";
diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs
index 9264fc8a735..bdb4d7c9df6 100644
--- a/src/librustc_parse/parser/mod.rs
+++ b/src/librustc_parse/parser/mod.rs
@@ -14,7 +14,7 @@ use crate::lexer::UnmatchedBrace;
 
 use log::debug;
 use rustc_ast::ast::DUMMY_NODE_ID;
-use rustc_ast::ast::{self, AttrStyle, AttrVec, Const, CrateSugar, Extern, Ident, Unsafe};
+use rustc_ast::ast::{self, AttrStyle, AttrVec, Const, CrateSugar, Extern, Unsafe};
 use rustc_ast::ast::{
     Async, MacArgs, MacDelimiter, Mutability, StrLit, Visibility, VisibilityKind,
 };
@@ -26,7 +26,7 @@ use rustc_ast_pretty::pprust;
 use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, FatalError, PResult};
 use rustc_session::parse::ParseSess;
 use rustc_span::source_map::{respan, Span, DUMMY_SP};
-use rustc_span::symbol::{kw, sym, Symbol};
+use rustc_span::symbol::{kw, sym, Ident, Symbol};
 
 use std::{cmp, mem, slice};
 
@@ -424,11 +424,11 @@ impl<'a> Parser<'a> {
     }
 
     // Public for rustfmt usage.
-    pub fn parse_ident(&mut self) -> PResult<'a, ast::Ident> {
+    pub fn parse_ident(&mut self) -> PResult<'a, Ident> {
         self.parse_ident_common(true)
     }
 
-    fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, ast::Ident> {
+    fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, Ident> {
         match self.token.ident() {
             Some((ident, is_raw)) => {
                 if !is_raw && ident.is_reserved() {
diff --git a/src/librustc_parse/parser/pat.rs b/src/librustc_parse/parser/pat.rs
index d588373425d..6603d0afc02 100644
--- a/src/librustc_parse/parser/pat.rs
+++ b/src/librustc_parse/parser/pat.rs
@@ -1,14 +1,14 @@
 use super::{Parser, PathStyle};
 use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
 use rustc_ast::ast::{self, AttrVec, Attribute, FieldPat, MacCall, Pat, PatKind, RangeEnd};
-use rustc_ast::ast::{BindingMode, Expr, ExprKind, Ident, Mutability, Path, QSelf, RangeSyntax};
+use rustc_ast::ast::{BindingMode, Expr, ExprKind, Mutability, Path, QSelf, RangeSyntax};
 use rustc_ast::mut_visit::{noop_visit_mac, noop_visit_pat, MutVisitor};
 use rustc_ast::ptr::P;
 use rustc_ast::token;
 use rustc_ast_pretty::pprust;
 use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, PResult};
 use rustc_span::source_map::{respan, Span, Spanned};
-use rustc_span::symbol::{kw, sym};
+use rustc_span::symbol::{kw, sym, Ident};
 
 type Expected = Option<&'static str>;
 
diff --git a/src/librustc_parse/parser/path.rs b/src/librustc_parse/parser/path.rs
index 9fa7bc027b8..5210614548d 100644
--- a/src/librustc_parse/parser/path.rs
+++ b/src/librustc_parse/parser/path.rs
@@ -3,12 +3,12 @@ use super::{Parser, TokenType};
 use crate::maybe_whole;
 use rustc_ast::ast::{self, AngleBracketedArg, AngleBracketedArgs, GenericArg, ParenthesizedArgs};
 use rustc_ast::ast::{AnonConst, AssocTyConstraint, AssocTyConstraintKind, BlockCheckMode};
-use rustc_ast::ast::{Ident, Path, PathSegment, QSelf};
+use rustc_ast::ast::{Path, PathSegment, QSelf};
 use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Token};
 use rustc_errors::{pluralize, Applicability, PResult};
 use rustc_span::source_map::{BytePos, Span};
-use rustc_span::symbol::{kw, sym};
+use rustc_span::symbol::{kw, sym, Ident};
 
 use log::debug;
 use std::mem;
diff --git a/src/librustc_passes/dead.rs b/src/librustc_passes/dead.rs
index 22ff87efd2e..1dcf0e7c7a9 100644
--- a/src/librustc_passes/dead.rs
+++ b/src/librustc_passes/dead.rs
@@ -16,7 +16,7 @@ use rustc_middle::ty::{self, DefIdTree, TyCtxt};
 use rustc_session::lint;
 
 use rustc_ast::{ast, attr};
-use rustc_span::symbol::sym;
+use rustc_span::symbol::{sym, Symbol};
 
 // Any local node that may call something in its body block should be
 // explored. For example, if it's a live Node::Item that is a
@@ -229,7 +229,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
     fn visit_variant_data(
         &mut self,
         def: &'tcx hir::VariantData<'tcx>,
-        _: ast::Name,
+        _: Symbol,
         _: &hir::Generics<'_>,
         _: hir::HirId,
         _: rustc_span::Span,
@@ -551,7 +551,7 @@ impl DeadVisitor<'tcx> {
         &mut self,
         id: hir::HirId,
         span: rustc_span::Span,
-        name: ast::Name,
+        name: Symbol,
         participle: &str,
     ) {
         if !name.as_str().starts_with('_') {
diff --git a/src/librustc_passes/liveness.rs b/src/librustc_passes/liveness.rs
index 8f736c1dd54..75ac8e731b5 100644
--- a/src/librustc_passes/liveness.rs
+++ b/src/librustc_passes/liveness.rs
@@ -96,7 +96,6 @@
 use self::LiveNodeKind::*;
 use self::VarKind::*;
 
-use rustc_ast::ast;
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
@@ -108,7 +107,7 @@ use rustc_middle::hir::map::Map;
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_session::lint;
-use rustc_span::symbol::sym;
+use rustc_span::symbol::{sym, Symbol};
 use rustc_span::Span;
 
 use std::collections::VecDeque;
@@ -245,13 +244,13 @@ struct CaptureInfo {
 #[derive(Copy, Clone, Debug)]
 struct LocalInfo {
     id: HirId,
-    name: ast::Name,
+    name: Symbol,
     is_shorthand: bool,
 }
 
 #[derive(Copy, Clone, Debug)]
 enum VarKind {
-    Param(HirId, ast::Name),
+    Param(HirId, Symbol),
     Local(LocalInfo),
     CleanExit,
 }
diff --git a/src/librustc_plugin_impl/load.rs b/src/librustc_plugin_impl/load.rs
index f48d2b6c8b5..c3a60166968 100644
--- a/src/librustc_plugin_impl/load.rs
+++ b/src/librustc_plugin_impl/load.rs
@@ -1,12 +1,12 @@
 //! Used by `rustc` when loading a plugin.
 
 use crate::Registry;
-use rustc_ast::ast::{Crate, Ident};
+use rustc_ast::ast::Crate;
 use rustc_errors::struct_span_err;
 use rustc_metadata::locator;
 use rustc_middle::middle::cstore::MetadataLoader;
 use rustc_session::Session;
-use rustc_span::symbol::sym;
+use rustc_span::symbol::{sym, Ident};
 use rustc_span::Span;
 
 use std::borrow::ToOwned;
diff --git a/src/librustc_privacy/Cargo.toml b/src/librustc_privacy/Cargo.toml
index 34146113f0e..6110d2ef7fc 100644
--- a/src/librustc_privacy/Cargo.toml
+++ b/src/librustc_privacy/Cargo.toml
@@ -15,7 +15,6 @@ rustc_errors = { path = "../librustc_errors" }
 rustc_hir = { path = "../librustc_hir" }
 rustc_typeck = { path = "../librustc_typeck" }
 rustc_session = { path = "../librustc_session" }
-rustc_ast = { path = "../librustc_ast" }
 rustc_span = { path = "../librustc_span" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 log = "0.4"
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 82b45cf7cf8..917e2f54830 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -4,7 +4,6 @@
 #![feature(or_patterns)]
 #![recursion_limit = "256"]
 
-use rustc_ast::ast::Ident;
 use rustc_attr as attr;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::struct_span_err;
@@ -22,7 +21,7 @@ use rustc_middle::ty::subst::InternalSubsts;
 use rustc_middle::ty::{self, GenericParamDefKind, TraitRef, Ty, TyCtxt, TypeFoldable};
 use rustc_session::lint;
 use rustc_span::hygiene::Transparency;
-use rustc_span::symbol::{kw, sym};
+use rustc_span::symbol::{kw, sym, Ident};
 use rustc_span::Span;
 
 use std::marker::PhantomData;
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index bd484fc7a90..d0eb1cfc222 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -17,7 +17,6 @@ use crate::{Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, Segmen
 
 use rustc_ast::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind, NodeId};
 use rustc_ast::ast::{AssocItem, AssocItemKind, MetaItemKind, StmtKind};
-use rustc_ast::ast::{Ident, Name};
 use rustc_ast::token::{self, Token};
 use rustc_ast::visit::{self, AssocCtxt, Visitor};
 use rustc_attr as attr;
@@ -34,7 +33,7 @@ use rustc_middle::middle::cstore::CrateStore;
 use rustc_middle::ty;
 use rustc_span::hygiene::{ExpnId, MacroKind};
 use rustc_span::source_map::{respan, Spanned};
-use rustc_span::symbol::{kw, sym};
+use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{Span, DUMMY_SP};
 
 use log::debug;
@@ -293,7 +292,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
         self.insert_field_names(def_id, field_names);
     }
 
-    fn insert_field_names(&mut self, def_id: DefId, field_names: Vec<Spanned<Name>>) {
+    fn insert_field_names(&mut self, def_id: DefId, field_names: Vec<Spanned<Symbol>>) {
         if !field_names.is_empty() {
             self.r.field_names.insert(def_id, field_names);
         }
@@ -953,7 +952,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
 
     fn add_macro_use_binding(
         &mut self,
-        name: ast::Name,
+        name: Symbol,
         binding: &'a NameBinding<'a>,
         span: Span,
         allow_shadowing: bool,
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index 8e82480c630..c66e9a60406 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -2,7 +2,7 @@ use std::cmp::Reverse;
 use std::ptr;
 
 use log::debug;
-use rustc_ast::ast::{self, Ident, Path};
+use rustc_ast::ast::{self, Path};
 use rustc_ast::util::lev_distance::find_best_match_for_name;
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::FxHashSet;
@@ -16,7 +16,7 @@ use rustc_middle::ty::{self, DefIdTree};
 use rustc_session::Session;
 use rustc_span::hygiene::MacroKind;
 use rustc_span::source_map::SourceMap;
-use rustc_span::symbol::{kw, Symbol};
+use rustc_span::symbol::{kw, Ident, Symbol};
 use rustc_span::{BytePos, MultiSpan, Span};
 
 use crate::imports::{Import, ImportKind, ImportResolver};
diff --git a/src/librustc_resolve/imports.rs b/src/librustc_resolve/imports.rs
index 5324e370dbd..a1e05d21b58 100644
--- a/src/librustc_resolve/imports.rs
+++ b/src/librustc_resolve/imports.rs
@@ -9,7 +9,7 @@ use crate::{BindingKey, ModuleKind, ResolutionError, Resolver, Segment};
 use crate::{CrateLint, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet, Weak};
 use crate::{NameBinding, NameBindingKind, PathResult, PrivacyError, ToNameBinding};
 
-use rustc_ast::ast::{Ident, Name, NodeId};
+use rustc_ast::ast::NodeId;
 use rustc_ast::unwrap_or;
 use rustc_ast::util::lev_distance::find_best_match_for_name;
 use rustc_data_structures::fx::FxHashSet;
@@ -24,7 +24,7 @@ use rustc_session::lint::builtin::{PUB_USE_OF_PRIVATE_EXTERN_CRATE, UNUSED_IMPOR
 use rustc_session::lint::BuiltinLintDiagnostics;
 use rustc_session::DiagnosticMessageId;
 use rustc_span::hygiene::ExpnId;
-use rustc_span::symbol::kw;
+use rustc_span::symbol::{kw, Ident, Symbol};
 use rustc_span::{MultiSpan, Span};
 
 use log::*;
@@ -57,7 +57,7 @@ pub enum ImportKind<'a> {
                                        // n.b. `max_vis` is only used in `finalize_import` to check for re-export errors.
     },
     ExternCrate {
-        source: Option<Name>,
+        source: Option<Symbol>,
         target: Ident,
     },
     MacroUse,
diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index 6214186a901..e541920e89e 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -24,7 +24,7 @@ use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX};
 use rustc_hir::TraitCandidate;
 use rustc_middle::{bug, span_bug};
 use rustc_session::lint;
-use rustc_span::symbol::{kw, sym};
+use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::Span;
 use smallvec::{smallvec, SmallVec};
 
@@ -1194,7 +1194,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
 
     fn check_trait_item<F>(&mut self, ident: Ident, ns: Namespace, span: Span, err: F)
     where
-        F: FnOnce(Name, &str) -> ResolutionError<'_>,
+        F: FnOnce(Symbol, &str) -> ResolutionError<'_>,
     {
         // If there is a TraitRef in scope for an impl, then the method must be in the
         // trait.
diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs
index 6041a56d366..dc92b465c2b 100644
--- a/src/librustc_resolve/late/diagnostics.rs
+++ b/src/librustc_resolve/late/diagnostics.rs
@@ -5,7 +5,7 @@ use crate::path_names_to_string;
 use crate::{CrateLint, Module, ModuleKind, ModuleOrUniformRoot};
 use crate::{PathResult, PathSource, Segment};
 
-use rustc_ast::ast::{self, Expr, ExprKind, Ident, Item, ItemKind, NodeId, Path, Ty, TyKind};
+use rustc_ast::ast::{self, Expr, ExprKind, Item, ItemKind, NodeId, Path, Ty, TyKind};
 use rustc_ast::util::lev_distance::find_best_match_for_name;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
@@ -16,7 +16,7 @@ use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX};
 use rustc_hir::PrimTy;
 use rustc_session::config::nightly_options;
 use rustc_span::hygiene::MacroKind;
-use rustc_span::symbol::{kw, sym};
+use rustc_span::symbol::{kw, sym, Ident};
 use rustc_span::Span;
 
 use log::debug;
@@ -1047,7 +1047,7 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
         err: &mut DiagnosticBuilder<'_>,
         span: Span,
         count: usize,
-        lifetime_names: &FxHashSet<ast::Ident>,
+        lifetime_names: &FxHashSet<Ident>,
         params: &[ElisionFailureInfo],
     ) {
         let snippet = self.tcx.sess.source_map().span_to_snippet(span).ok();
diff --git a/src/librustc_resolve/late/lifetimes.rs b/src/librustc_resolve/late/lifetimes.rs
index a062330ba4b..a3fbb28f22a 100644
--- a/src/librustc_resolve/late/lifetimes.rs
+++ b/src/librustc_resolve/late/lifetimes.rs
@@ -6,7 +6,6 @@
 //! way. Therefore, we break lifetime name resolution into a separate pass.
 
 use crate::late::diagnostics::{ForLifetimeSpanType, MissingLifetimeSpot};
-use rustc_ast::ast;
 use rustc_ast::attr;
 use rustc_ast::walk_list;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -22,7 +21,7 @@ use rustc_middle::middle::resolve_lifetime::*;
 use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt};
 use rustc_middle::{bug, span_bug};
 use rustc_session::lint;
-use rustc_span::symbol::{kw, sym};
+use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::Span;
 use std::borrow::Cow;
 use std::cell::Cell;
@@ -175,7 +174,7 @@ crate struct LifetimeContext<'a, 'tcx> {
     is_in_fn_syntax: bool,
 
     /// List of labels in the function/method currently under analysis.
-    labels_in_fn: Vec<ast::Ident>,
+    labels_in_fn: Vec<Ident>,
 
     /// Cache for cross-crate per-definition object lifetime defaults.
     xcrate_object_lifetime_defaults: DefIdMap<Vec<ObjectLifetimeDefault>>,
@@ -1064,7 +1063,7 @@ fn check_mixed_explicit_and_in_band_defs(tcx: TyCtxt<'_>, params: &[hir::Generic
     }
 }
 
-fn signal_shadowing_problem(tcx: TyCtxt<'_>, name: ast::Name, orig: Original, shadower: Shadower) {
+fn signal_shadowing_problem(tcx: TyCtxt<'_>, name: Symbol, orig: Original, shadower: Shadower) {
     let mut err = if let (ShadowKind::Lifetime, ShadowKind::Lifetime) = (orig.kind, shadower.kind) {
         // lifetime/lifetime shadowing is an error
         struct_span_err!(
@@ -1102,7 +1101,7 @@ fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body<'_>) {
     struct GatherLabels<'a, 'tcx> {
         tcx: TyCtxt<'tcx>,
         scope: ScopeRef<'a>,
-        labels_in_fn: &'a mut Vec<ast::Ident>,
+        labels_in_fn: &'a mut Vec<Ident>,
     }
 
     let mut gather =
@@ -1138,15 +1137,11 @@ fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body<'_>) {
         }
     }
 
-    fn expression_label(ex: &hir::Expr<'_>) -> Option<ast::Ident> {
+    fn expression_label(ex: &hir::Expr<'_>) -> Option<Ident> {
         if let hir::ExprKind::Loop(_, Some(label), _) = ex.kind { Some(label.ident) } else { None }
     }
 
-    fn check_if_label_shadows_lifetime(
-        tcx: TyCtxt<'_>,
-        mut scope: ScopeRef<'_>,
-        label: ast::Ident,
-    ) {
+    fn check_if_label_shadows_lifetime(tcx: TyCtxt<'_>, mut scope: ScopeRef<'_>, label: Ident) {
         loop {
             match *scope {
                 Scope::Body { s, .. }
@@ -1360,11 +1355,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
 
     /// helper method to determine the span to remove when suggesting the
     /// deletion of a lifetime
-    fn lifetime_deletion_span(
-        &self,
-        name: ast::Ident,
-        generics: &hir::Generics<'_>,
-    ) -> Option<Span> {
+    fn lifetime_deletion_span(&self, name: Ident, generics: &hir::Generics<'_>) -> Option<Span> {
         generics.params.iter().enumerate().find_map(|(i, param)| {
             if param.name.ident() == name {
                 let mut in_band = false;
@@ -2394,7 +2385,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
         if let Some(params) = error {
             // If there's no lifetime available, suggest `'static`.
             if self.report_elision_failure(&mut err, params) && lifetime_names.is_empty() {
-                lifetime_names.insert(ast::Ident::from_str("'static"));
+                lifetime_names.insert(Ident::from_str("'static"));
             }
         }
         self.add_missing_lifetime_specifiers_label(
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index d33eaf5a827..2031b7868c0 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -17,7 +17,7 @@ pub use rustc_hir::def::{Namespace, PerNS};
 
 use Determinacy::*;
 
-use rustc_ast::ast::{self, FloatTy, Ident, IntTy, Name, NodeId, UintTy};
+use rustc_ast::ast::{self, FloatTy, IntTy, NodeId, UintTy};
 use rustc_ast::ast::{Crate, CRATE_NODE_ID};
 use rustc_ast::ast::{ItemKind, Path};
 use rustc_ast::attr;
@@ -47,7 +47,7 @@ use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
 use rustc_session::Session;
 use rustc_span::hygiene::{ExpnId, ExpnKind, MacroKind, SyntaxContext, Transparency};
 use rustc_span::source_map::Spanned;
-use rustc_span::symbol::{kw, sym};
+use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{Span, DUMMY_SP};
 
 use log::debug;
@@ -147,7 +147,7 @@ impl<'a> ParentScope<'a> {
 
 #[derive(Eq)]
 struct BindingError {
-    name: Name,
+    name: Symbol,
     origin: BTreeSet<Span>,
     target: BTreeSet<Span>,
     could_be_path: bool,
@@ -176,23 +176,23 @@ enum ResolutionError<'a> {
     GenericParamsFromOuterFunction(Res, HasGenericParams),
     /// Error E0403: the name is already used for a type or const parameter in this generic
     /// parameter list.
-    NameAlreadyUsedInParameterList(Name, Span),
+    NameAlreadyUsedInParameterList(Symbol, Span),
     /// Error E0407: method is not a member of trait.
-    MethodNotMemberOfTrait(Name, &'a str),
+    MethodNotMemberOfTrait(Symbol, &'a str),
     /// Error E0437: type is not a member of trait.
-    TypeNotMemberOfTrait(Name, &'a str),
+    TypeNotMemberOfTrait(Symbol, &'a str),
     /// Error E0438: const is not a member of trait.
-    ConstNotMemberOfTrait(Name, &'a str),
+    ConstNotMemberOfTrait(Symbol, &'a str),
     /// Error E0408: variable `{}` is not bound in all patterns.
     VariableNotBoundInPattern(&'a BindingError),
     /// Error E0409: variable `{}` is bound in inconsistent ways within the same match arm.
-    VariableBoundWithDifferentMode(Name, Span),
+    VariableBoundWithDifferentMode(Symbol, Span),
     /// Error E0415: identifier is bound more than once in this parameter list.
     IdentifierBoundMoreThanOnceInParameterList(&'a str),
     /// Error E0416: identifier is bound more than once in the same pattern.
     IdentifierBoundMoreThanOnceInSamePattern(&'a str),
     /// Error E0426: use of undeclared label.
-    UndeclaredLabel(&'a str, Option<Name>),
+    UndeclaredLabel(&'a str, Option<Symbol>),
     /// Error E0429: `self` imports are only allowed within a `{ }` list.
     SelfImportsOnlyAllowedWithin,
     /// Error E0430: `self` import can only appear once in the list.
@@ -206,7 +206,7 @@ enum ResolutionError<'a> {
     /// Error E0435: attempt to use a non-constant value in a constant.
     AttemptToUseNonConstantValueInConstant,
     /// Error E0530: `X` bindings cannot shadow `Y`s.
-    BindingShadowsSomethingUnacceptable(&'a str, Name, &'a NameBinding<'a>),
+    BindingShadowsSomethingUnacceptable(&'a str, Symbol, &'a NameBinding<'a>),
     /// Error E0128: type parameters with a default cannot use forward-declared identifiers.
     ForwardDeclaredTyParam, // FIXME(const_generics:defaults)
     /// Error E0735: type parameters with a default cannot use `Self`
@@ -406,12 +406,12 @@ enum ModuleKind {
     /// * A normal module ‒ either `mod from_file;` or `mod from_block { }`.
     /// * A trait or an enum (it implicitly contains associated types, methods and variant
     ///   constructors).
-    Def(DefKind, DefId, Name),
+    Def(DefKind, DefId, Symbol),
 }
 
 impl ModuleKind {
     /// Get name of the module.
-    pub fn name(&self) -> Option<Name> {
+    pub fn name(&self) -> Option<Symbol> {
         match self {
             ModuleKind::Block(..) => None,
             ModuleKind::Def(.., name) => Some(*name),
@@ -786,7 +786,7 @@ impl<'a> NameBinding<'a> {
 /// All other types are defined somewhere and possibly imported, but the primitive ones need
 /// special handling, since they have no place of origin.
 struct PrimitiveTypeTable {
-    primitive_types: FxHashMap<Name, PrimTy>,
+    primitive_types: FxHashMap<Symbol, PrimTy>,
 }
 
 impl PrimitiveTypeTable {
@@ -838,7 +838,7 @@ pub struct Resolver<'a> {
 
     /// Names of fields of an item `DefId` accessible with dot syntax.
     /// Used for hints during error reporting.
-    field_names: FxHashMap<DefId, Vec<Spanned<Name>>>,
+    field_names: FxHashMap<DefId, Vec<Spanned<Symbol>>>,
 
     /// All imports known to succeed or fail.
     determined_imports: Vec<&'a Import<'a>>,
@@ -913,11 +913,11 @@ pub struct Resolver<'a> {
 
     crate_loader: CrateLoader<'a>,
     macro_names: FxHashSet<Ident>,
-    builtin_macros: FxHashMap<Name, SyntaxExtension>,
+    builtin_macros: FxHashMap<Symbol, SyntaxExtension>,
     registered_attrs: FxHashSet<Ident>,
     registered_tools: FxHashSet<Ident>,
-    macro_use_prelude: FxHashMap<Name, &'a NameBinding<'a>>,
-    all_macros: FxHashMap<Name, Res>,
+    macro_use_prelude: FxHashMap<Symbol, &'a NameBinding<'a>>,
+    all_macros: FxHashMap<Symbol, Res>,
     macro_map: FxHashMap<DefId, Lrc<SyntaxExtension>>,
     dummy_ext_bang: Lrc<SyntaxExtension>,
     dummy_ext_derive: Lrc<SyntaxExtension>,
@@ -947,7 +947,7 @@ pub struct Resolver<'a> {
     helper_attrs: FxHashMap<ExpnId, Vec<Ident>>,
 
     /// Avoid duplicated errors for "name already defined".
-    name_already_seen: FxHashMap<Name, Span>,
+    name_already_seen: FxHashMap<Symbol, Span>,
 
     potentially_unused_imports: Vec<&'a Import<'a>>,
 
@@ -956,7 +956,7 @@ pub struct Resolver<'a> {
     struct_constructors: DefIdMap<(Res, ty::Visibility)>,
 
     /// Features enabled for this crate.
-    active_features: FxHashSet<Name>,
+    active_features: FxHashSet<Symbol>,
 
     /// Stores enum visibilities to properly build a reduced graph
     /// when visiting the correspondent variants.
@@ -1044,8 +1044,8 @@ impl rustc_ast_lowering::Resolver for Resolver<'_> {
     fn resolve_str_path(
         &mut self,
         span: Span,
-        crate_root: Option<Name>,
-        components: &[Name],
+        crate_root: Option<Symbol>,
+        components: &[Symbol],
         ns: Namespace,
     ) -> (ast::Path, Res) {
         let root = if crate_root.is_some() { kw::PathRoot } else { kw::Crate };
@@ -2678,7 +2678,7 @@ impl<'a> Resolver<'a> {
     fn add_suggestion_for_rename_of_use(
         &self,
         err: &mut DiagnosticBuilder<'_>,
-        name: Name,
+        name: Symbol,
         import: &Import<'_>,
         binding_span: Span,
     ) {
@@ -2914,12 +2914,12 @@ impl<'a> Resolver<'a> {
     }
 
     // For rustdoc.
-    pub fn all_macros(&self) -> &FxHashMap<Name, Res> {
+    pub fn all_macros(&self) -> &FxHashMap<Symbol, Res> {
         &self.all_macros
     }
 }
 
-fn names_to_string(names: &[Name]) -> String {
+fn names_to_string(names: &[Symbol]) -> String {
     let mut result = String::new();
     for (i, name) in names.iter().filter(|name| **name != kw::PathRoot).enumerate() {
         if i > 0 {
@@ -2941,14 +2941,14 @@ fn path_names_to_string(path: &Path) -> String {
 fn module_to_string(module: Module<'_>) -> Option<String> {
     let mut names = Vec::new();
 
-    fn collect_mod(names: &mut Vec<Name>, module: Module<'_>) {
+    fn collect_mod(names: &mut Vec<Symbol>, module: Module<'_>) {
         if let ModuleKind::Def(.., name) = module.kind {
             if let Some(parent) = module.parent {
                 names.push(name);
                 collect_mod(names, parent);
             }
         } else {
-            names.push(Name::intern("<opaque>"));
+            names.push(Symbol::intern("<opaque>"));
             collect_mod(names, module.parent.unwrap());
         }
     }
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index aa78ac60945..1b6268dc8cb 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -6,7 +6,7 @@ use crate::Namespace::*;
 use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, Determinacy};
 use crate::{CrateLint, ParentScope, ResolutionError, Resolver, Scope, ScopeSet, Weak};
 use crate::{ModuleKind, ModuleOrUniformRoot, NameBinding, PathResult, Segment, ToNameBinding};
-use rustc_ast::ast::{self, Ident, NodeId};
+use rustc_ast::ast::{self, NodeId};
 use rustc_ast_pretty::pprust;
 use rustc_attr::{self as attr, StabilityLevel};
 use rustc_data_structures::fx::FxHashSet;
@@ -23,7 +23,7 @@ use rustc_session::lint::builtin::UNUSED_MACROS;
 use rustc_session::Session;
 use rustc_span::edition::Edition;
 use rustc_span::hygiene::{self, ExpnData, ExpnId, ExpnKind};
-use rustc_span::symbol::{kw, sym, Symbol};
+use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{Span, DUMMY_SP};
 
 use rustc_data_structures::sync::Lrc;
@@ -165,7 +165,7 @@ impl<'a> base::Resolver for Resolver<'a> {
         parent_scope.module.unexpanded_invocations.borrow_mut().remove(&expansion);
     }
 
-    fn register_builtin_macro(&mut self, ident: ast::Ident, ext: SyntaxExtension) {
+    fn register_builtin_macro(&mut self, ident: Ident, ext: SyntaxExtension) {
         if self.builtin_macros.insert(ident.name, ext).is_some() {
             self.session
                 .span_err(ident.span, &format!("built-in macro `{}` was already defined", ident));
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index ccce72fb0ac..534fe172bef 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -26,6 +26,7 @@ use rustc_middle::span_bug;
 use rustc_middle::ty::{self, DefIdTree, TyCtxt};
 use rustc_session::config::Input;
 use rustc_span::source_map::{respan, DUMMY_SP};
+use rustc_span::symbol::Ident;
 use rustc_span::*;
 
 use std::env;
@@ -264,7 +265,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
         sig: &'l ast::FnSig,
         body: Option<&'l ast::Block>,
         id: ast::NodeId,
-        ident: ast::Ident,
+        ident: Ident,
         generics: &'l ast::Generics,
         vis: ast::Visibility,
         span: Span,
@@ -419,7 +420,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
     fn process_assoc_const(
         &mut self,
         id: ast::NodeId,
-        ident: ast::Ident,
+        ident: Ident,
         typ: &'l ast::Ty,
         expr: Option<&'l ast::Expr>,
         parent_id: DefId,
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index 8456a0304fe..8ae6853210f 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -24,6 +24,7 @@ use rustc_middle::{bug, span_bug};
 use rustc_session::config::{CrateType, Input, OutputType};
 use rustc_session::output::{filename_for_metadata, out_filename};
 use rustc_span::source_map::Spanned;
+use rustc_span::symbol::Ident;
 use rustc_span::*;
 
 use std::cell::Cell;
@@ -405,7 +406,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
 
     // FIXME would be nice to take a MethodItem here, but the ast provides both
     // trait and impl flavours, so the caller must do the disassembly.
-    pub fn get_method_data(&self, id: ast::NodeId, ident: ast::Ident, span: Span) -> Option<Def> {
+    pub fn get_method_data(&self, id: ast::NodeId, ident: Ident, span: Span) -> Option<Def> {
         // The qualname for a method is the trait name or name of the struct in an impl in
         // which the method is declared in, followed by the method's name.
         let (qualname, parent_scope, decl_id, docs, attributes) = match self
@@ -914,7 +915,7 @@ fn make_signature(decl: &ast::FnDecl, generics: &ast::Generics) -> String {
 // variables (idents) from patterns.
 struct PathCollector<'l> {
     collected_paths: Vec<(NodeId, &'l ast::Path)>,
-    collected_idents: Vec<(NodeId, ast::Ident, ast::Mutability)>,
+    collected_idents: Vec<(NodeId, Ident, ast::Mutability)>,
 }
 
 impl<'l> PathCollector<'l> {
diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs
index a2b973cda91..bda9ff93b02 100644
--- a/src/librustc_save_analysis/sig.rs
+++ b/src/librustc_save_analysis/sig.rs
@@ -32,6 +32,7 @@ use rls_data::{SigElement, Signature};
 use rustc_ast::ast::{self, Extern, NodeId};
 use rustc_ast_pretty::pprust;
 use rustc_hir::def::{DefKind, Res};
+use rustc_span::symbol::{Ident, Symbol};
 
 pub fn item_signature(item: &ast::Item, scx: &SaveContext<'_, '_>) -> Option<Signature> {
     if !scx.config.signatures {
@@ -69,7 +70,7 @@ pub fn variant_signature(variant: &ast::Variant, scx: &SaveContext<'_, '_>) -> O
 
 pub fn method_signature(
     id: NodeId,
-    ident: ast::Ident,
+    ident: Ident,
     generics: &ast::Generics,
     m: &ast::FnSig,
     scx: &SaveContext<'_, '_>,
@@ -82,7 +83,7 @@ pub fn method_signature(
 
 pub fn assoc_const_signature(
     id: NodeId,
-    ident: ast::Name,
+    ident: Symbol,
     ty: &ast::Ty,
     default: Option<&ast::Expr>,
     scx: &SaveContext<'_, '_>,
@@ -95,7 +96,7 @@ pub fn assoc_const_signature(
 
 pub fn assoc_type_signature(
     id: NodeId,
-    ident: ast::Ident,
+    ident: Ident,
     bounds: Option<&ast::GenericBounds>,
     default: Option<&ast::Ty>,
     scx: &SaveContext<'_, '_>,
@@ -803,7 +804,7 @@ fn name_and_generics(
     offset: usize,
     generics: &ast::Generics,
     id: NodeId,
-    name: ast::Ident,
+    name: Ident,
     scx: &SaveContext<'_, '_>,
 ) -> Result {
     let name = name.to_string();
@@ -821,7 +822,7 @@ fn name_and_generics(
 
 fn make_assoc_type_signature(
     id: NodeId,
-    ident: ast::Ident,
+    ident: Ident,
     bounds: Option<&ast::GenericBounds>,
     default: Option<&ast::Ty>,
     scx: &SaveContext<'_, '_>,
@@ -853,7 +854,7 @@ fn make_assoc_type_signature(
 
 fn make_assoc_const_signature(
     id: NodeId,
-    ident: ast::Name,
+    ident: Symbol,
     ty: &ast::Ty,
     default: Option<&ast::Expr>,
     scx: &SaveContext<'_, '_>,
@@ -884,7 +885,7 @@ fn make_assoc_const_signature(
 
 fn make_method_signature(
     id: NodeId,
-    ident: ast::Ident,
+    ident: Ident,
     generics: &ast::Generics,
     m: &ast::FnSig,
     scx: &SaveContext<'_, '_>,
diff --git a/src/librustc_session/options.rs b/src/librustc_session/options.rs
index 1d314238b86..4eabb55e6df 100644
--- a/src/librustc_session/options.rs
+++ b/src/librustc_session/options.rs
@@ -768,6 +768,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
         "select which borrowck is used (`mir` or `migrate`) (default: `migrate`)"),
     borrowck_stats: bool = (false, parse_bool, [UNTRACKED],
         "gather borrowck statistics (default: no)"),
+    chalk: bool = (false, parse_bool, [TRACKED],
+        "enable the experimental Chalk-based trait solving engine"),
     codegen_backend: Option<String> = (None, parse_opt_string, [TRACKED],
         "the backend to use"),
     control_flow_guard: CFGuard = (CFGuard::Disabled, parse_cfguard, [UNTRACKED],
@@ -1008,6 +1010,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
         `mir` (the MIR), or `mir-cfg` (graphviz formatted MIR)"),
     unstable_options: bool = (false, parse_bool, [UNTRACKED],
         "adds unstable command line options to rustc interface (default: no)"),
+    use_ctors_section: Option<bool> = (None, parse_opt_bool, [TRACKED],
+        "use legacy .ctors section for initializers rather than .init_array"),
     verbose: bool = (false, parse_bool, [UNTRACKED],
         "in general, enable more debug printouts (default: no)"),
     verify_llvm_ir: bool = (false, parse_bool, [TRACKED],
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index 51dce9e144c..477161dc658 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -882,6 +882,10 @@ pub struct TargetOptions {
 
     /// Additional arguments to pass to LLVM, similar to the `-C llvm-args` codegen option.
     pub llvm_args: Vec<String>,
+
+    /// Whether to use legacy .ctors initialization hooks rather than .init_array. Defaults
+    /// to false (uses .init_array).
+    pub use_ctors_section: bool,
 }
 
 impl Default for TargetOptions {
@@ -972,6 +976,7 @@ impl Default for TargetOptions {
             llvm_abiname: "".to_string(),
             relax_elf_relocations: false,
             llvm_args: vec![],
+            use_ctors_section: false,
         }
     }
 }
@@ -1312,6 +1317,7 @@ impl Target {
         key!(llvm_abiname);
         key!(relax_elf_relocations, bool);
         key!(llvm_args, list);
+        key!(use_ctors_section, bool);
 
         if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) {
             for name in array.iter().filter_map(|abi| abi.as_string()) {
@@ -1541,6 +1547,7 @@ impl ToJson for Target {
         target_option_val!(llvm_abiname);
         target_option_val!(relax_elf_relocations);
         target_option_val!(llvm_args);
+        target_option_val!(use_ctors_section);
 
         if default.abi_blacklist != self.options.abi_blacklist {
             d.insert(
diff --git a/src/librustc_target/spec/netbsd_base.rs b/src/librustc_target/spec/netbsd_base.rs
index 95c4749f9c7..988346af2d7 100644
--- a/src/librustc_target/spec/netbsd_base.rs
+++ b/src/librustc_target/spec/netbsd_base.rs
@@ -23,6 +23,7 @@ pub fn opts() -> TargetOptions {
         pre_link_args: args,
         position_independent_executables: true,
         relro_level: RelroLevel::Full,
+        use_ctors_section: true,
         ..Default::default()
     }
 }
diff --git a/src/librustc_trait_selection/traits/chalk_fulfill.rs b/src/librustc_trait_selection/traits/chalk_fulfill.rs
new file mode 100644
index 00000000000..115e4a0e629
--- /dev/null
+++ b/src/librustc_trait_selection/traits/chalk_fulfill.rs
@@ -0,0 +1,262 @@
+//! Defines a Chalk-based `TraitEngine`
+
+use crate::infer::canonical::OriginalQueryValues;
+use crate::infer::InferCtxt;
+use crate::traits::query::NoSolution;
+use crate::traits::{
+    ChalkEnvironmentAndGoal, ChalkEnvironmentClause, FulfillmentError, FulfillmentErrorCode,
+    ObligationCause, PredicateObligation, SelectionError, TraitEngine,
+};
+use rustc_data_structures::fx::FxHashSet;
+use rustc_hir::def_id::DefId;
+use rustc_middle::ty::{self, Ty, TyCtxt};
+
+pub struct FulfillmentContext<'tcx> {
+    obligations: FxHashSet<PredicateObligation<'tcx>>,
+}
+
+impl FulfillmentContext<'tcx> {
+    crate fn new() -> Self {
+        FulfillmentContext { obligations: FxHashSet::default() }
+    }
+}
+
+fn environment<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    def_id: DefId,
+) -> &'tcx ty::List<ChalkEnvironmentClause<'tcx>> {
+    use rustc_hir::{ForeignItemKind, ImplItemKind, ItemKind, Node, TraitItemKind};
+    use rustc_middle::ty::subst::GenericArgKind;
+
+    debug!("environment(def_id = {:?})", def_id);
+
+    // The environment of an impl Trait type is its defining function's environment.
+    if let Some(parent) = ty::is_impl_trait_defn(tcx, def_id) {
+        return environment(tcx, parent);
+    }
+
+    // Compute the bounds on `Self` and the type parameters.
+    let ty::InstantiatedPredicates { predicates, .. } =
+        tcx.predicates_of(def_id).instantiate_identity(tcx);
+
+    let clauses = predicates.into_iter().map(|pred| ChalkEnvironmentClause::Predicate(pred));
+
+    let hir_id = tcx.hir().as_local_hir_id(def_id.expect_local());
+    let node = tcx.hir().get(hir_id);
+
+    enum NodeKind {
+        TraitImpl,
+        InherentImpl,
+        Fn,
+        Other,
+    };
+
+    let node_kind = match node {
+        Node::TraitItem(item) => match item.kind {
+            TraitItemKind::Fn(..) => NodeKind::Fn,
+            _ => NodeKind::Other,
+        },
+
+        Node::ImplItem(item) => match item.kind {
+            ImplItemKind::Fn(..) => NodeKind::Fn,
+            _ => NodeKind::Other,
+        },
+
+        Node::Item(item) => match item.kind {
+            ItemKind::Impl { of_trait: Some(_), .. } => NodeKind::TraitImpl,
+            ItemKind::Impl { of_trait: None, .. } => NodeKind::InherentImpl,
+            ItemKind::Fn(..) => NodeKind::Fn,
+            _ => NodeKind::Other,
+        },
+
+        Node::ForeignItem(item) => match item.kind {
+            ForeignItemKind::Fn(..) => NodeKind::Fn,
+            _ => NodeKind::Other,
+        },
+
+        // FIXME: closures?
+        _ => NodeKind::Other,
+    };
+
+    // FIXME(eddyb) isn't the unordered nature of this a hazard?
+    let mut inputs = FxHashSet::default();
+
+    match node_kind {
+        // In a trait impl, we assume that the header trait ref and all its
+        // constituents are well-formed.
+        NodeKind::TraitImpl => {
+            let trait_ref = tcx.impl_trait_ref(def_id).expect("not an impl");
+
+            inputs.extend(trait_ref.substs.iter().flat_map(|&arg| arg.walk()));
+        }
+
+        // In an inherent impl, we assume that the receiver type and all its
+        // constituents are well-formed.
+        NodeKind::InherentImpl => {
+            let self_ty = tcx.type_of(def_id);
+            inputs.extend(self_ty.walk());
+        }
+
+        // In an fn, we assume that the arguments and all their constituents are
+        // well-formed.
+        NodeKind::Fn => {
+            let fn_sig = tcx.fn_sig(def_id);
+            let fn_sig = tcx.liberate_late_bound_regions(def_id, &fn_sig);
+
+            inputs.extend(fn_sig.inputs().iter().flat_map(|ty| ty.walk()));
+        }
+
+        NodeKind::Other => (),
+    }
+    let input_clauses = inputs.into_iter().filter_map(|arg| {
+        match arg.unpack() {
+            GenericArgKind::Type(ty) => Some(ChalkEnvironmentClause::TypeFromEnv(ty)),
+
+            // FIXME(eddyb) no WF conditions from lifetimes?
+            GenericArgKind::Lifetime(_) => None,
+
+            // FIXME(eddyb) support const generics in Chalk
+            GenericArgKind::Const(_) => None,
+        }
+    });
+
+    tcx.mk_chalk_environment_clause_list(clauses.chain(input_clauses))
+}
+
+/// We need to wrap a `ty::Predicate` in an elaborated environment *before* we
+/// canonicalize. This is due to the fact that we insert extra clauses into the
+/// environment for all input types (`FromEnv`).
+fn in_environment(
+    infcx: &InferCtxt<'_, 'tcx>,
+    obligation: &PredicateObligation<'tcx>,
+) -> ChalkEnvironmentAndGoal<'tcx> {
+    assert!(!infcx.is_in_snapshot());
+    let obligation = infcx.resolve_vars_if_possible(obligation);
+
+    let environment = match obligation.param_env.def_id {
+        Some(def_id) => environment(infcx.tcx, def_id),
+        None if obligation.param_env.caller_bounds.is_empty() => ty::List::empty(),
+        _ => bug!("non-empty `ParamEnv` with no def-id"),
+    };
+
+    ChalkEnvironmentAndGoal { environment, goal: obligation.predicate }
+}
+
+impl TraitEngine<'tcx> for FulfillmentContext<'tcx> {
+    fn normalize_projection_type(
+        &mut self,
+        infcx: &InferCtxt<'_, 'tcx>,
+        _param_env: ty::ParamEnv<'tcx>,
+        projection_ty: ty::ProjectionTy<'tcx>,
+        _cause: ObligationCause<'tcx>,
+    ) -> Ty<'tcx> {
+        infcx.tcx.mk_ty(ty::Projection(projection_ty))
+    }
+
+    fn register_predicate_obligation(
+        &mut self,
+        infcx: &InferCtxt<'_, 'tcx>,
+        obligation: PredicateObligation<'tcx>,
+    ) {
+        assert!(!infcx.is_in_snapshot());
+        let obligation = infcx.resolve_vars_if_possible(&obligation);
+
+        self.obligations.insert(obligation);
+    }
+
+    fn select_all_or_error(
+        &mut self,
+        infcx: &InferCtxt<'_, 'tcx>,
+    ) -> Result<(), Vec<FulfillmentError<'tcx>>> {
+        self.select_where_possible(infcx)?;
+
+        if self.obligations.is_empty() {
+            Ok(())
+        } else {
+            let errors = self
+                .obligations
+                .iter()
+                .map(|obligation| FulfillmentError {
+                    obligation: obligation.clone(),
+                    code: FulfillmentErrorCode::CodeAmbiguity,
+                    points_at_arg_span: false,
+                })
+                .collect();
+            Err(errors)
+        }
+    }
+
+    fn select_where_possible(
+        &mut self,
+        infcx: &InferCtxt<'_, 'tcx>,
+    ) -> Result<(), Vec<FulfillmentError<'tcx>>> {
+        let mut errors = Vec::new();
+        let mut next_round = FxHashSet::default();
+        let mut making_progress;
+
+        loop {
+            making_progress = false;
+
+            // We iterate over all obligations, and record if we are able
+            // to unambiguously prove at least one obligation.
+            for obligation in self.obligations.drain() {
+                let goal_in_environment = in_environment(infcx, &obligation);
+                let mut orig_values = OriginalQueryValues::default();
+                let canonical_goal =
+                    infcx.canonicalize_query(&goal_in_environment, &mut orig_values);
+
+                match infcx.tcx.evaluate_goal(canonical_goal) {
+                    Ok(response) => {
+                        if response.is_proven() {
+                            making_progress = true;
+
+                            match infcx.instantiate_query_response_and_region_obligations(
+                                &obligation.cause,
+                                obligation.param_env,
+                                &orig_values,
+                                &response,
+                            ) {
+                                Ok(infer_ok) => next_round.extend(
+                                    infer_ok.obligations.into_iter().map(|obligation| {
+                                        assert!(!infcx.is_in_snapshot());
+                                        infcx.resolve_vars_if_possible(&obligation)
+                                    }),
+                                ),
+
+                                Err(_err) => errors.push(FulfillmentError {
+                                    obligation: obligation,
+                                    code: FulfillmentErrorCode::CodeSelectionError(
+                                        SelectionError::Unimplemented,
+                                    ),
+                                    points_at_arg_span: false,
+                                }),
+                            }
+                        } else {
+                            // Ambiguous: retry at next round.
+                            next_round.insert(obligation);
+                        }
+                    }
+
+                    Err(NoSolution) => errors.push(FulfillmentError {
+                        obligation: obligation,
+                        code: FulfillmentErrorCode::CodeSelectionError(
+                            SelectionError::Unimplemented,
+                        ),
+                        points_at_arg_span: false,
+                    }),
+                }
+            }
+            next_round = std::mem::replace(&mut self.obligations, next_round);
+
+            if !making_progress {
+                break;
+            }
+        }
+
+        if errors.is_empty() { Ok(()) } else { Err(errors) }
+    }
+
+    fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>> {
+        self.obligations.iter().map(|obligation| obligation.clone()).collect()
+    }
+}
diff --git a/src/librustc_trait_selection/traits/engine.rs b/src/librustc_trait_selection/traits/engine.rs
index c6a3dfa698e..4d477886979 100644
--- a/src/librustc_trait_selection/traits/engine.rs
+++ b/src/librustc_trait_selection/traits/engine.rs
@@ -1,14 +1,18 @@
 use rustc_middle::ty::TyCtxt;
 
-use super::FulfillmentContext;
 use super::TraitEngine;
+use super::{ChalkFulfillmentContext, FulfillmentContext};
 
 pub trait TraitEngineExt<'tcx> {
     fn new(tcx: TyCtxt<'tcx>) -> Box<Self>;
 }
 
 impl<'tcx> TraitEngineExt<'tcx> for dyn TraitEngine<'tcx> {
-    fn new(_tcx: TyCtxt<'tcx>) -> Box<Self> {
-        Box::new(FulfillmentContext::new())
+    fn new(tcx: TyCtxt<'tcx>) -> Box<Self> {
+        if tcx.sess.opts.debugging_opts.chalk {
+            Box::new(ChalkFulfillmentContext::new())
+        } else {
+            Box::new(FulfillmentContext::new())
+        }
     }
 }
diff --git a/src/librustc_trait_selection/traits/error_reporting/mod.rs b/src/librustc_trait_selection/traits/error_reporting/mod.rs
index 6c51afa9660..405c656bad5 100644
--- a/src/librustc_trait_selection/traits/error_reporting/mod.rs
+++ b/src/librustc_trait_selection/traits/error_reporting/mod.rs
@@ -570,12 +570,21 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                     }
 
                     ty::Predicate::WellFormed(ty) => {
-                        // WF predicates cannot themselves make
-                        // errors. They can only block due to
-                        // ambiguity; otherwise, they always
-                        // degenerate into other obligations
-                        // (which may fail).
-                        span_bug!(span, "WF predicate not satisfied for {:?}", ty);
+                        if !self.tcx.sess.opts.debugging_opts.chalk {
+                            // WF predicates cannot themselves make
+                            // errors. They can only block due to
+                            // ambiguity; otherwise, they always
+                            // degenerate into other obligations
+                            // (which may fail).
+                            span_bug!(span, "WF predicate not satisfied for {:?}", ty);
+                        } else {
+                            // FIXME: we'll need a better message which takes into account
+                            // which bounds actually failed to hold.
+                            self.tcx.sess.struct_span_err(
+                                span,
+                                &format!("the type `{}` is not well-formed (chalk)", ty),
+                            )
+                        }
                     }
 
                     ty::Predicate::ConstEvaluatable(..) => {
diff --git a/src/librustc_trait_selection/traits/mod.rs b/src/librustc_trait_selection/traits/mod.rs
index c5dbe816295..778430fc2ca 100644
--- a/src/librustc_trait_selection/traits/mod.rs
+++ b/src/librustc_trait_selection/traits/mod.rs
@@ -4,6 +4,7 @@
 
 #[allow(dead_code)]
 pub mod auto_trait;
+mod chalk_fulfill;
 pub mod codegen;
 mod coherence;
 mod engine;
@@ -69,6 +70,8 @@ pub use self::util::{
     supertrait_def_ids, supertraits, transitive_bounds, SupertraitDefIds, Supertraits,
 };
 
+pub use self::chalk_fulfill::FulfillmentContext as ChalkFulfillmentContext;
+
 pub use rustc_infer::traits::*;
 
 /// Whether to skip the leak check, as part of a future compatibility warning step.
diff --git a/src/librustc_trait_selection/traits/project.rs b/src/librustc_trait_selection/traits/project.rs
index bf0e1ed7b89..47df82690e0 100644
--- a/src/librustc_trait_selection/traits/project.rs
+++ b/src/librustc_trait_selection/traits/project.rs
@@ -17,14 +17,13 @@ use super::{VtableClosureData, VtableFnPointerData, VtableGeneratorData, VtableI
 use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
 use crate::traits::error_reporting::InferCtxtExt;
-use rustc_ast::ast::Ident;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_errors::ErrorReported;
 use rustc_hir::def_id::DefId;
 use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
 use rustc_middle::ty::subst::{InternalSubsts, Subst};
 use rustc_middle::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, WithConstness};
-use rustc_span::symbol::sym;
+use rustc_span::symbol::{sym, Ident};
 use rustc_span::DUMMY_SP;
 
 pub use rustc_middle::traits::Reveal;
diff --git a/src/librustc_trait_selection/traits/select.rs b/src/librustc_trait_selection/traits/select.rs
index 27d3b2ec9cb..b595f77e4d6 100644
--- a/src/librustc_trait_selection/traits/select.rs
+++ b/src/librustc_trait_selection/traits/select.rs
@@ -2877,11 +2877,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             trait_ref,
         )?);
 
-        obligations.push(Obligation::new(
-            obligation.cause.clone(),
-            obligation.param_env,
-            ty::Predicate::ClosureKind(closure_def_id, substs, kind),
-        ));
+        // FIXME: Chalk
+
+        if !self.tcx().sess.opts.debugging_opts.chalk {
+            obligations.push(Obligation::new(
+                obligation.cause.clone(),
+                obligation.param_env,
+                ty::Predicate::ClosureKind(closure_def_id, substs, kind),
+            ));
+        }
 
         Ok(VtableClosureData { closure_def_id, substs, nested: obligations })
     }
diff --git a/src/librustc_traits/Cargo.toml b/src/librustc_traits/Cargo.toml
index 839558f38fd..e485bc2929b 100644
--- a/src/librustc_traits/Cargo.toml
+++ b/src/librustc_traits/Cargo.toml
@@ -13,8 +13,12 @@ log = { version = "0.4" }
 rustc_middle = { path = "../librustc_middle" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_hir = { path = "../librustc_hir" }
+rustc_index = { path = "../librustc_index" }
 rustc_ast = { path = "../librustc_ast" }
 rustc_span = { path = "../librustc_span" }
+chalk-ir = "0.10.0"
+chalk-rust-ir = "0.10.0"
+chalk-solve = "0.10.0"
 smallvec = { version = "1.0", features = ["union", "may_dangle"] }
 rustc_infer = { path = "../librustc_infer" }
 rustc_trait_selection = { path = "../librustc_trait_selection" }
diff --git a/src/librustc_traits/chalk/db.rs b/src/librustc_traits/chalk/db.rs
new file mode 100644
index 00000000000..0cec583bb56
--- /dev/null
+++ b/src/librustc_traits/chalk/db.rs
@@ -0,0 +1,521 @@
+//! Provides the `RustIrDatabase` implementation for `chalk-solve`
+//!
+//! The purpose of the `chalk_solve::RustIrDatabase` is to get data about
+//! specific types, such as bounds, where clauses, or fields. This file contains
+//! the minimal logic to assemble the types for `chalk-solve` by calling out to
+//! either the `TyCtxt` (for information about types) or
+//! `crate::chalk::lowering` (to lower rustc types into Chalk types).
+
+use rustc_middle::traits::{ChalkRustDefId as RustDefId, ChalkRustInterner as RustInterner};
+use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef};
+use rustc_middle::ty::{self, AssocItemContainer, AssocKind, TyCtxt};
+
+use rustc_hir::def_id::DefId;
+
+use rustc_span::symbol::sym;
+
+use std::fmt;
+use std::sync::Arc;
+
+use crate::chalk::lowering::LowerInto;
+
+pub struct RustIrDatabase<'tcx> {
+    pub tcx: TyCtxt<'tcx>,
+    pub interner: RustInterner<'tcx>,
+}
+
+impl fmt::Debug for RustIrDatabase<'_> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "RustIrDatabase")
+    }
+}
+
+impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'tcx> {
+    fn interner(&self) -> &RustInterner<'tcx> {
+        &self.interner
+    }
+
+    fn associated_ty_data(
+        &self,
+        assoc_type_id: chalk_ir::AssocTypeId<RustInterner<'tcx>>,
+    ) -> Arc<chalk_rust_ir::AssociatedTyDatum<RustInterner<'tcx>>> {
+        let def_id = match assoc_type_id.0 {
+            RustDefId::AssocTy(def_id) => def_id,
+            _ => bug!("Did not use `AssocTy` variant when expecting associated type."),
+        };
+        let assoc_item = self.tcx.associated_item(def_id);
+        let trait_def_id = match assoc_item.container {
+            AssocItemContainer::TraitContainer(def_id) => def_id,
+            _ => unimplemented!("Not possible??"),
+        };
+        match assoc_item.kind {
+            AssocKind::Type => {}
+            _ => unimplemented!("Not possible??"),
+        }
+        let bound_vars = bound_vars_for_item(self.tcx, def_id);
+        let binders = binders_for(&self.interner, bound_vars);
+        // FIXME(chalk): this really isn't right I don't think. The functions
+        // for GATs are a bit hard to figure out. Are these supposed to be where
+        // clauses or bounds?
+        let predicates = self.tcx.predicates_defined_on(def_id).predicates;
+        let where_clauses: Vec<_> = predicates
+            .into_iter()
+            .map(|(wc, _)| wc.subst(self.tcx, &bound_vars))
+            .filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner)).collect();
+
+        Arc::new(chalk_rust_ir::AssociatedTyDatum {
+            trait_id: chalk_ir::TraitId(RustDefId::Trait(trait_def_id)),
+            id: assoc_type_id,
+            name: (),
+            binders: chalk_ir::Binders::new(
+                binders,
+                chalk_rust_ir::AssociatedTyDatumBound { bounds: vec![], where_clauses },
+            ),
+        })
+    }
+
+    fn trait_datum(
+        &self,
+        trait_id: chalk_ir::TraitId<RustInterner<'tcx>>,
+    ) -> Arc<chalk_rust_ir::TraitDatum<RustInterner<'tcx>>> {
+        let def_id = match trait_id.0 {
+            RustDefId::Trait(def_id) => def_id,
+            _ => bug!("Did not use `Trait` variant when expecting trait."),
+        };
+        let trait_def = self.tcx.trait_def(def_id);
+
+        let bound_vars = bound_vars_for_item(self.tcx, def_id);
+        let binders = binders_for(&self.interner, bound_vars);
+        let predicates = self.tcx.predicates_defined_on(def_id).predicates;
+        let where_clauses: Vec<_> = predicates
+            .into_iter()
+            .map(|(wc, _)| wc.subst(self.tcx, &bound_vars))
+            .filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner)).collect();
+
+        let well_known =
+            if self.tcx.lang_items().sized_trait().map(|t| def_id == t).unwrap_or(false) {
+                Some(chalk_rust_ir::WellKnownTrait::SizedTrait)
+            } else if self.tcx.lang_items().copy_trait().map(|t| def_id == t).unwrap_or(false) {
+                Some(chalk_rust_ir::WellKnownTrait::CopyTrait)
+            } else if self.tcx.lang_items().clone_trait().map(|t| def_id == t).unwrap_or(false) {
+                Some(chalk_rust_ir::WellKnownTrait::CloneTrait)
+            } else {
+                None
+            };
+        Arc::new(chalk_rust_ir::TraitDatum {
+            id: trait_id,
+            binders: chalk_ir::Binders::new(
+                binders,
+                chalk_rust_ir::TraitDatumBound { where_clauses },
+            ),
+            flags: chalk_rust_ir::TraitFlags {
+                auto: trait_def.has_auto_impl,
+                marker: trait_def.is_marker,
+                upstream: !def_id.is_local(),
+                fundamental: self.tcx.has_attr(def_id, sym::fundamental),
+                non_enumerable: true,
+                coinductive: false,
+            },
+            associated_ty_ids: vec![],
+            well_known,
+        })
+    }
+
+    fn struct_datum(
+        &self,
+        struct_id: chalk_ir::StructId<RustInterner<'tcx>>,
+    ) -> Arc<chalk_rust_ir::StructDatum<RustInterner<'tcx>>> {
+        match struct_id.0 {
+            RustDefId::Adt(adt_def_id) => {
+                let adt_def = self.tcx.adt_def(adt_def_id);
+
+                let bound_vars = bound_vars_for_item(self.tcx, adt_def_id);
+                let binders = binders_for(&self.interner, bound_vars);
+
+                let predicates = self.tcx.predicates_of(adt_def_id).predicates;
+                let where_clauses: Vec<_> = predicates
+                    .into_iter()
+                    .map(|(wc, _)| wc.subst(self.tcx, bound_vars))
+                    .filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner))
+                    .collect();
+                let fields = match adt_def.adt_kind() {
+                    ty::AdtKind::Struct | ty::AdtKind::Union => {
+                        let variant = adt_def.non_enum_variant();
+                        variant
+                            .fields
+                            .iter()
+                            .map(|field| {
+                                self.tcx
+                                    .type_of(field.did)
+                                    .subst(self.tcx, bound_vars)
+                                    .lower_into(&self.interner)
+                            })
+                            .collect()
+                    }
+                    // FIXME(chalk): handle enums; force_impl_for requires this
+                    ty::AdtKind::Enum => vec![],
+                };
+                let struct_datum = Arc::new(chalk_rust_ir::StructDatum {
+                    id: struct_id,
+                    binders: chalk_ir::Binders::new(
+                        binders,
+                        chalk_rust_ir::StructDatumBound { fields, where_clauses },
+                    ),
+                    flags: chalk_rust_ir::StructFlags {
+                        upstream: !adt_def_id.is_local(),
+                        fundamental: adt_def.is_fundamental(),
+                    },
+                });
+                return struct_datum;
+            }
+            RustDefId::Ref(_) => {
+                return Arc::new(chalk_rust_ir::StructDatum {
+                    id: struct_id,
+                    binders: chalk_ir::Binders::new(
+                        chalk_ir::ParameterKinds::from(
+                            &self.interner,
+                            vec![
+                                chalk_ir::ParameterKind::Lifetime(()),
+                                chalk_ir::ParameterKind::Ty(()),
+                            ],
+                        ),
+                        chalk_rust_ir::StructDatumBound { fields: vec![], where_clauses: vec![] },
+                    ),
+                    flags: chalk_rust_ir::StructFlags { upstream: false, fundamental: false },
+                });
+            }
+            RustDefId::Array | RustDefId::Slice => {
+                return Arc::new(chalk_rust_ir::StructDatum {
+                    id: struct_id,
+                    binders: chalk_ir::Binders::new(
+                        chalk_ir::ParameterKinds::from(
+                            &self.interner,
+                            Some(chalk_ir::ParameterKind::Ty(())),
+                        ),
+                        chalk_rust_ir::StructDatumBound { fields: vec![], where_clauses: vec![] },
+                    ),
+                    flags: chalk_rust_ir::StructFlags { upstream: false, fundamental: false },
+                });
+            }
+            RustDefId::Str | RustDefId::Never | RustDefId::FnDef(_) => {
+                return Arc::new(chalk_rust_ir::StructDatum {
+                    id: struct_id,
+                    binders: chalk_ir::Binders::new(
+                        chalk_ir::ParameterKinds::new(&self.interner),
+                        chalk_rust_ir::StructDatumBound { fields: vec![], where_clauses: vec![] },
+                    ),
+                    flags: chalk_rust_ir::StructFlags { upstream: false, fundamental: false },
+                });
+            }
+
+            _ => bug!("Used not struct variant when expecting struct variant."),
+        }
+    }
+
+    fn impl_datum(
+        &self,
+        impl_id: chalk_ir::ImplId<RustInterner<'tcx>>,
+    ) -> Arc<chalk_rust_ir::ImplDatum<RustInterner<'tcx>>> {
+        let def_id = match impl_id.0 {
+            RustDefId::Impl(def_id) => def_id,
+            _ => bug!("Did not use `Impl` variant when expecting impl."),
+        };
+        let bound_vars = bound_vars_for_item(self.tcx, def_id);
+        let binders = binders_for(&self.interner, bound_vars);
+
+        let trait_ref = self.tcx.impl_trait_ref(def_id).expect("not an impl");
+        let trait_ref = trait_ref.subst(self.tcx, bound_vars);
+
+        let predicates = self.tcx.predicates_of(def_id).predicates;
+        let where_clauses: Vec<_> = predicates
+            .into_iter()
+            .map(|(wc, _)| wc.subst(self.tcx, bound_vars))
+            .filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner)).collect();
+
+        let value = chalk_rust_ir::ImplDatumBound {
+            trait_ref: trait_ref.lower_into(&self.interner),
+            where_clauses,
+        };
+
+        Arc::new(chalk_rust_ir::ImplDatum {
+            polarity: chalk_rust_ir::Polarity::Positive,
+            binders: chalk_ir::Binders::new(binders, value),
+            impl_type: chalk_rust_ir::ImplType::Local,
+            associated_ty_value_ids: vec![],
+        })
+    }
+
+    fn impls_for_trait(
+        &self,
+        trait_id: chalk_ir::TraitId<RustInterner<'tcx>>,
+        parameters: &[chalk_ir::Parameter<RustInterner<'tcx>>],
+    ) -> Vec<chalk_ir::ImplId<RustInterner<'tcx>>> {
+        let def_id: DefId = match trait_id.0 {
+            RustDefId::Trait(def_id) => def_id,
+            _ => bug!("Did not use `Trait` variant when expecting trait."),
+        };
+
+        // FIXME(chalk): use TraitDef::for_each_relevant_impl, but that will
+        // require us to be able to interconvert `Ty<'tcx>`, and we're
+        // not there yet.
+
+        let all_impls = self.tcx.all_impls(def_id);
+        let matched_impls = all_impls.into_iter().filter(|impl_def_id| {
+            use chalk_ir::could_match::CouldMatch;
+            let trait_ref = self.tcx.impl_trait_ref(*impl_def_id).unwrap();
+            let bound_vars = bound_vars_for_item(self.tcx, *impl_def_id);
+
+            let self_ty = trait_ref.self_ty();
+            let self_ty = self_ty.subst(self.tcx, bound_vars);
+            let lowered_ty = self_ty.lower_into(&self.interner);
+
+            parameters[0].assert_ty_ref(&self.interner).could_match(&self.interner, &lowered_ty)
+        });
+
+        let impls = matched_impls
+            .map(|matched_impl| chalk_ir::ImplId(RustDefId::Impl(matched_impl)))
+            .collect();
+        impls
+    }
+
+    fn impl_provided_for(
+        &self,
+        auto_trait_id: chalk_ir::TraitId<RustInterner<'tcx>>,
+        struct_id: chalk_ir::StructId<RustInterner<'tcx>>,
+    ) -> bool {
+        let trait_def_id: DefId = match auto_trait_id.0 {
+            RustDefId::Trait(def_id) => def_id,
+            _ => bug!("Did not use `Trait` variant when expecting trait."),
+        };
+        let adt_def_id: DefId = match struct_id.0 {
+            RustDefId::Adt(def_id) => def_id,
+            _ => bug!("Did not use `Adt` variant when expecting adt."),
+        };
+        let all_impls = self.tcx.all_impls(trait_def_id);
+        for impl_def_id in all_impls {
+            let trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap();
+            let self_ty = trait_ref.self_ty();
+            match self_ty.kind {
+                ty::Adt(adt_def, _) => {
+                    if adt_def.did == adt_def_id {
+                        return true;
+                    }
+                }
+                _ => {}
+            }
+        }
+        return false;
+    }
+
+    fn associated_ty_value(
+        &self,
+        associated_ty_id: chalk_rust_ir::AssociatedTyValueId<RustInterner<'tcx>>,
+    ) -> Arc<chalk_rust_ir::AssociatedTyValue<RustInterner<'tcx>>> {
+        let def_id = match associated_ty_id.0 {
+            RustDefId::AssocTy(def_id) => def_id,
+            _ => bug!("Did not use `AssocTy` variant when expecting associated type."),
+        };
+        let assoc_item = self.tcx.associated_item(def_id);
+        let impl_id = match assoc_item.container {
+            AssocItemContainer::TraitContainer(def_id) => def_id,
+            _ => unimplemented!("Not possible??"),
+        };
+        match assoc_item.kind {
+            AssocKind::Type => {}
+            _ => unimplemented!("Not possible??"),
+        }
+        let bound_vars = bound_vars_for_item(self.tcx, def_id);
+        let binders = binders_for(&self.interner, bound_vars);
+        let ty = self.tcx.type_of(def_id);
+
+        Arc::new(chalk_rust_ir::AssociatedTyValue {
+            impl_id: chalk_ir::ImplId(RustDefId::Impl(impl_id)),
+            associated_ty_id: chalk_ir::AssocTypeId(RustDefId::AssocTy(def_id)),
+            value: chalk_ir::Binders::new(
+                binders,
+                chalk_rust_ir::AssociatedTyValueBound { ty: ty.lower_into(&self.interner) },
+            ),
+        })
+    }
+
+    fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<RustInterner<'tcx>>> {
+        vec![]
+    }
+
+    fn local_impls_to_coherence_check(
+        &self,
+        _trait_id: chalk_ir::TraitId<RustInterner<'tcx>>,
+    ) -> Vec<chalk_ir::ImplId<RustInterner<'tcx>>> {
+        unimplemented!()
+    }
+
+    fn opaque_ty_data(
+        &self,
+        _id: chalk_ir::OpaqueTyId<RustInterner<'tcx>>,
+    ) -> Arc<chalk_rust_ir::OpaqueTyDatum<RustInterner<'tcx>>> {
+        unimplemented!()
+    }
+
+    /// Since Chalk can't handle all Rust types currently, we have to handle
+    /// some specially for now. Over time, these `Some` returns will change to
+    /// `None` and eventually this function will be removed.
+    fn force_impl_for(
+        &self,
+        well_known: chalk_rust_ir::WellKnownTrait,
+        ty: &chalk_ir::TyData<RustInterner<'tcx>>,
+    ) -> Option<bool> {
+        use chalk_ir::TyData::*;
+        match well_known {
+            chalk_rust_ir::WellKnownTrait::SizedTrait => match ty {
+                Apply(apply) => match apply.name {
+                    chalk_ir::TypeName::Struct(chalk_ir::StructId(rust_def_id)) => {
+                        use rustc_middle::traits::ChalkRustDefId::*;
+                        match rust_def_id {
+                            Never | Array | RawPtr | FnDef(_) | Ref(_) => Some(true),
+
+                            Adt(adt_def_id) => {
+                                let adt_def = self.tcx.adt_def(adt_def_id);
+                                match adt_def.adt_kind() {
+                                    ty::AdtKind::Struct | ty::AdtKind::Union => None,
+                                    ty::AdtKind::Enum => {
+                                        let constraint = self.tcx.adt_sized_constraint(adt_def_id);
+                                        if constraint.0.len() > 0 {
+                                            unimplemented!()
+                                        } else {
+                                            Some(true)
+                                        }
+                                    }
+                                }
+                            }
+
+                            Str | Slice => Some(false),
+
+                            Trait(_) | Impl(_) | AssocTy(_) => panic!(),
+                        }
+                    }
+                    _ => None,
+                },
+                Dyn(_) | Alias(_) | Placeholder(_) | Function(_) | InferenceVar(_)
+                | BoundVar(_) => None,
+            },
+            chalk_rust_ir::WellKnownTrait::CopyTrait
+            | chalk_rust_ir::WellKnownTrait::CloneTrait => match ty {
+                Apply(apply) => match apply.name {
+                    chalk_ir::TypeName::Struct(chalk_ir::StructId(rust_def_id)) => {
+                        use rustc_middle::traits::ChalkRustDefId::*;
+                        match rust_def_id {
+                            Never | RawPtr | Ref(_) | Str | Slice => Some(false),
+                            FnDef(_) | Array => Some(true),
+                            Adt(adt_def_id) => {
+                                let adt_def = self.tcx.adt_def(adt_def_id);
+                                match adt_def.adt_kind() {
+                                    ty::AdtKind::Struct | ty::AdtKind::Union => None,
+                                    ty::AdtKind::Enum => {
+                                        let constraint = self.tcx.adt_sized_constraint(adt_def_id);
+                                        if constraint.0.len() > 0 {
+                                            unimplemented!()
+                                        } else {
+                                            Some(true)
+                                        }
+                                    }
+                                }
+                            }
+                            Trait(_) | Impl(_) | AssocTy(_) => panic!(),
+                        }
+                    }
+                    _ => None,
+                },
+                Dyn(_) | Alias(_) | Placeholder(_) | Function(_) | InferenceVar(_)
+                | BoundVar(_) => None,
+            },
+            chalk_rust_ir::WellKnownTrait::DropTrait => None,
+        }
+    }
+
+    fn program_clauses_for_env(
+        &self,
+        environment: &chalk_ir::Environment<RustInterner<'tcx>>,
+    ) -> chalk_ir::ProgramClauses<RustInterner<'tcx>> {
+        chalk_solve::program_clauses_for_env(self, environment)
+    }
+
+    fn well_known_trait_id(
+        &self,
+        well_known_trait: chalk_rust_ir::WellKnownTrait,
+    ) -> Option<chalk_ir::TraitId<RustInterner<'tcx>>> {
+        use chalk_rust_ir::WellKnownTrait::*;
+        let t = match well_known_trait {
+            SizedTrait => self
+                .tcx
+                .lang_items()
+                .sized_trait()
+                .map(|t| chalk_ir::TraitId(RustDefId::Trait(t)))
+                .unwrap(),
+            CopyTrait => self
+                .tcx
+                .lang_items()
+                .copy_trait()
+                .map(|t| chalk_ir::TraitId(RustDefId::Trait(t)))
+                .unwrap(),
+            CloneTrait => self
+                .tcx
+                .lang_items()
+                .clone_trait()
+                .map(|t| chalk_ir::TraitId(RustDefId::Trait(t)))
+                .unwrap(),
+            DropTrait => self
+                .tcx
+                .lang_items()
+                .drop_trait()
+                .map(|t| chalk_ir::TraitId(RustDefId::Trait(t)))
+                .unwrap(),
+        };
+        Some(t)
+    }
+}
+
+/// Creates a `InternalSubsts` that maps each generic parameter to a higher-ranked
+/// var bound at index `0`. For types, we use a `BoundVar` index equal to
+/// the type parameter index. For regions, we use the `BoundRegion::BrNamed`
+/// variant (which has a `DefId`).
+fn bound_vars_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> SubstsRef<'tcx> {
+    InternalSubsts::for_item(tcx, def_id, |param, substs| match param.kind {
+        ty::GenericParamDefKind::Type { .. } => tcx
+            .mk_ty(ty::Bound(
+                ty::INNERMOST,
+                ty::BoundTy {
+                    var: ty::BoundVar::from(param.index),
+                    kind: ty::BoundTyKind::Param(param.name),
+                },
+            ))
+            .into(),
+
+        ty::GenericParamDefKind::Lifetime => tcx
+            .mk_region(ty::RegionKind::ReLateBound(
+                ty::INNERMOST,
+                ty::BoundRegion::BrAnon(substs.len() as u32),
+            ))
+            .into(),
+
+        ty::GenericParamDefKind::Const => tcx
+            .mk_const(ty::Const {
+                val: ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from(param.index)),
+                ty: tcx.type_of(param.def_id),
+            })
+            .into(),
+    })
+}
+
+fn binders_for<'tcx>(
+    interner: &RustInterner<'tcx>,
+    bound_vars: SubstsRef<'tcx>,
+) -> chalk_ir::ParameterKinds<RustInterner<'tcx>> {
+    chalk_ir::ParameterKinds::from(
+        interner,
+        bound_vars.iter().map(|arg| match arg.unpack() {
+            ty::subst::GenericArgKind::Lifetime(_re) => chalk_ir::ParameterKind::Lifetime(()),
+            ty::subst::GenericArgKind::Type(_ty) => chalk_ir::ParameterKind::Ty(()),
+            ty::subst::GenericArgKind::Const(_const) => chalk_ir::ParameterKind::Ty(()),
+        }),
+    )
+}
diff --git a/src/librustc_traits/chalk/lowering.rs b/src/librustc_traits/chalk/lowering.rs
new file mode 100644
index 00000000000..4dc15a6b2b6
--- /dev/null
+++ b/src/librustc_traits/chalk/lowering.rs
@@ -0,0 +1,722 @@
+//! Contains the logic to lower rustc types into Chalk types
+//!
+//! In many cases there is a 1:1 relationship between a rustc type and a Chalk type.
+//! For example, a `SubstsRef` maps almost directly to a `Substitution`. In some
+//! other cases, such as `Param`s, there is no Chalk type, so we have to handle
+//! accordingly.
+//!
+//! ## `Ty` lowering
+//! Much of the `Ty` lowering is 1:1 with Chalk. (Or will be eventually). A
+//! helpful table for what types lower to what can be found in the
+//! [Chalk book](http://rust-lang.github.io/chalk/book/types/rust_types.html).
+//! The most notable difference lies with `Param`s. To convert from rustc to
+//! Chalk, we eagerly and deeply convert `Param`s to placeholders (in goals) or
+//! bound variables (for clause generation through functions in `db`).
+//!
+//! ## `Region` lowering
+//! Regions are handled in rustc and Chalk is quite differently. In rustc, there
+//! is a difference between "early bound" and "late bound" regions, where only
+//! the late bound regions have a `DebruijnIndex`. Moreover, in Chalk all
+//! regions (Lifetimes) have an associated index. In rustc, only `BrAnon`s have
+//! an index, whereas `BrNamed` don't. In order to lower regions to Chalk, we
+//! convert all regions into `BrAnon` late-bound regions.
+//!
+//! ## `Const` lowering
+//! Chalk doesn't handle consts currently, so consts are currently lowered to
+//! an empty tuple.
+//!
+//! ## Bound variable collection
+//! Another difference between rustc and Chalk lies in the handling of binders.
+//! Chalk requires that we store the bound parameter kinds, whereas rustc does
+//! not. To lower anything wrapped in a `Binder`, we first deeply find any bound
+//! variables from the current `Binder`.
+
+use rustc_middle::traits::{
+    ChalkEnvironmentAndGoal, ChalkEnvironmentClause, ChalkRustDefId as RustDefId,
+    ChalkRustInterner as RustInterner,
+};
+use rustc_middle::ty::fold::TypeFolder;
+use rustc_middle::ty::subst::{GenericArg, SubstsRef};
+use rustc_middle::ty::{
+    self, Binder, BoundRegion, Predicate, Region, RegionKind, Ty, TyCtxt, TyKind, TypeFoldable,
+    TypeVisitor,
+};
+use rustc_span::def_id::DefId;
+
+use std::collections::btree_map::{BTreeMap, Entry};
+
+/// Essentially an `Into` with a `&RustInterner` parameter
+crate trait LowerInto<'tcx, T> {
+    /// Lower a rustc construct (e.g., `ty::TraitPredicate`) to a chalk type, consuming `self`.
+    fn lower_into(self, interner: &RustInterner<'tcx>) -> T;
+}
+
+impl<'tcx> LowerInto<'tcx, chalk_ir::Substitution<RustInterner<'tcx>>> for SubstsRef<'tcx> {
+    fn lower_into(
+        self,
+        interner: &RustInterner<'tcx>,
+    ) -> chalk_ir::Substitution<RustInterner<'tcx>> {
+        chalk_ir::Substitution::from(interner, self.iter().map(|s| s.lower_into(interner)))
+    }
+}
+
+impl<'tcx> LowerInto<'tcx, chalk_ir::AliasTy<RustInterner<'tcx>>> for ty::ProjectionTy<'tcx> {
+    fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::AliasTy<RustInterner<'tcx>> {
+        chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy {
+            associated_ty_id: chalk_ir::AssocTypeId(RustDefId::AssocTy(self.item_def_id)),
+            substitution: self.substs.lower_into(interner),
+        })
+    }
+}
+
+impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'tcx>>>>
+    for ChalkEnvironmentAndGoal<'tcx>
+{
+    fn lower_into(
+        self,
+        interner: &RustInterner<'tcx>,
+    ) -> chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'tcx>>> {
+        let clauses = self.environment.into_iter().filter_map(|clause| match clause {
+            ChalkEnvironmentClause::Predicate(predicate) => {
+                match predicate {
+                    ty::Predicate::Trait(predicate, _) => {
+                        let (predicate, binders, _named_regions) =
+                            collect_bound_vars(interner, interner.tcx, predicate);
+
+                        Some(
+                            chalk_ir::ProgramClauseData::ForAll(chalk_ir::Binders::new(
+                                binders,
+                                chalk_ir::ProgramClauseImplication {
+                                    consequence: chalk_ir::DomainGoal::FromEnv(
+                                        chalk_ir::FromEnv::Trait(
+                                            predicate.trait_ref.lower_into(interner),
+                                        ),
+                                    ),
+                                    conditions: chalk_ir::Goals::new(interner),
+                                    priority: chalk_ir::ClausePriority::High,
+                                },
+                            ))
+                            .intern(interner),
+                        )
+                    }
+                    // FIXME(chalk): need to add RegionOutlives/TypeOutlives
+                    ty::Predicate::RegionOutlives(_) => None,
+                    ty::Predicate::TypeOutlives(_) => None,
+                    ty::Predicate::Projection(predicate) => {
+                        let (predicate, binders, _named_regions) =
+                            collect_bound_vars(interner, interner.tcx, predicate);
+
+                        Some(
+                            chalk_ir::ProgramClauseData::ForAll(chalk_ir::Binders::new(
+                                binders,
+                                chalk_ir::ProgramClauseImplication {
+                                    consequence: chalk_ir::DomainGoal::Holds(
+                                        chalk_ir::WhereClause::AliasEq(
+                                            predicate.lower_into(interner),
+                                        ),
+                                    ),
+                                    conditions: chalk_ir::Goals::new(interner),
+                                    priority: chalk_ir::ClausePriority::High,
+                                },
+                            ))
+                            .intern(interner),
+                        )
+                    }
+                    ty::Predicate::WellFormed(..)
+                    | ty::Predicate::ObjectSafe(..)
+                    | ty::Predicate::ClosureKind(..)
+                    | ty::Predicate::Subtype(..)
+                    | ty::Predicate::ConstEvaluatable(..) => {
+                        bug!("unexpected predicate {}", predicate)
+                    }
+                }
+            }
+            ChalkEnvironmentClause::TypeFromEnv(ty) => Some(
+                chalk_ir::ProgramClauseData::Implies(chalk_ir::ProgramClauseImplication {
+                    consequence: chalk_ir::DomainGoal::FromEnv(chalk_ir::FromEnv::Ty(
+                        ty.lower_into(interner),
+                    )),
+                    conditions: chalk_ir::Goals::new(interner),
+                    priority: chalk_ir::ClausePriority::High,
+                })
+                .intern(interner),
+            ),
+        });
+
+        let goal: chalk_ir::GoalData<RustInterner<'tcx>> = self.goal.lower_into(&interner);
+        chalk_ir::InEnvironment {
+            environment: chalk_ir::Environment {
+                clauses: chalk_ir::ProgramClauses::from(&interner, clauses),
+            },
+            goal: goal.intern(&interner),
+        }
+    }
+}
+
+impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData<RustInterner<'tcx>>> for ty::Predicate<'tcx> {
+    fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::GoalData<RustInterner<'tcx>> {
+        match self {
+            Predicate::Trait(predicate, _) => predicate.lower_into(interner),
+            // FIXME(chalk): we need to register constraints.
+            Predicate::RegionOutlives(_predicate) => {
+                chalk_ir::GoalData::All(chalk_ir::Goals::new(interner))
+            }
+            Predicate::TypeOutlives(_predicate) => {
+                chalk_ir::GoalData::All(chalk_ir::Goals::new(interner))
+            }
+            Predicate::Projection(predicate) => predicate.lower_into(interner),
+            Predicate::WellFormed(ty) => match ty.kind {
+                // These types are always WF.
+                ty::Str | ty::Placeholder(..) | ty::Error | ty::Never => {
+                    chalk_ir::GoalData::All(chalk_ir::Goals::new(interner))
+                }
+
+                // FIXME(chalk): Well-formed only if ref lifetime outlives type
+                ty::Ref(..) => chalk_ir::GoalData::All(chalk_ir::Goals::new(interner)),
+
+                ty::Param(..) => panic!("No Params expected."),
+
+                // FIXME(chalk) -- ultimately I think this is what we
+                // want to do, and we just have rules for how to prove
+                // `WellFormed` for everything above, instead of
+                // inlining a bit the rules of the proof here.
+                _ => chalk_ir::GoalData::DomainGoal(chalk_ir::DomainGoal::WellFormed(
+                    chalk_ir::WellFormed::Ty(ty.lower_into(interner)),
+                )),
+            },
+
+            // FIXME(chalk): other predicates
+            //
+            // We can defer this, but ultimately we'll want to express
+            // some of these in terms of chalk operations.
+            Predicate::ObjectSafe(..)
+            | Predicate::ClosureKind(..)
+            | Predicate::Subtype(..)
+            | Predicate::ConstEvaluatable(..) => {
+                chalk_ir::GoalData::All(chalk_ir::Goals::new(interner))
+            }
+        }
+    }
+}
+
+impl<'tcx> LowerInto<'tcx, chalk_ir::TraitRef<RustInterner<'tcx>>>
+    for rustc_middle::ty::TraitRef<'tcx>
+{
+    fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::TraitRef<RustInterner<'tcx>> {
+        chalk_ir::TraitRef {
+            trait_id: chalk_ir::TraitId(RustDefId::Trait(self.def_id)),
+            substitution: self.substs.lower_into(interner),
+        }
+    }
+}
+
+impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData<RustInterner<'tcx>>>
+    for ty::PolyTraitPredicate<'tcx>
+{
+    fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::GoalData<RustInterner<'tcx>> {
+        let (ty, binders, _named_regions) = collect_bound_vars(interner, interner.tcx, &self);
+
+        chalk_ir::GoalData::Quantified(
+            chalk_ir::QuantifierKind::ForAll,
+            chalk_ir::Binders::new(
+                binders,
+                chalk_ir::GoalData::DomainGoal(chalk_ir::DomainGoal::Holds(
+                    chalk_ir::WhereClause::Implemented(ty.trait_ref.lower_into(interner)),
+                ))
+                .intern(interner),
+            ),
+        )
+    }
+}
+
+impl<'tcx> LowerInto<'tcx, chalk_ir::AliasEq<RustInterner<'tcx>>>
+    for rustc_middle::ty::ProjectionPredicate<'tcx>
+{
+    fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::AliasEq<RustInterner<'tcx>> {
+        chalk_ir::AliasEq {
+            ty: self.ty.lower_into(interner),
+            alias: self.projection_ty.lower_into(interner),
+        }
+    }
+}
+
+impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData<RustInterner<'tcx>>>
+    for ty::PolyProjectionPredicate<'tcx>
+{
+    fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::GoalData<RustInterner<'tcx>> {
+        let (ty, binders, _named_regions) = collect_bound_vars(interner, interner.tcx, &self);
+
+        chalk_ir::GoalData::Quantified(
+            chalk_ir::QuantifierKind::ForAll,
+            chalk_ir::Binders::new(
+                binders,
+                chalk_ir::GoalData::DomainGoal(chalk_ir::DomainGoal::Holds(
+                    chalk_ir::WhereClause::AliasEq(ty.lower_into(interner)),
+                ))
+                .intern(interner),
+            ),
+        )
+    }
+}
+
+impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> {
+    fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::Ty<RustInterner<'tcx>> {
+        use chalk_ir::TyData;
+        use rustc_ast::ast;
+        use TyKind::*;
+
+        let empty = || chalk_ir::Substitution::empty(interner);
+        let struct_ty = |def_id| chalk_ir::TypeName::Struct(chalk_ir::StructId(def_id));
+        let apply = |name, substitution| {
+            TyData::Apply(chalk_ir::ApplicationTy { name, substitution }).intern(interner)
+        };
+        let int = |i| apply(chalk_ir::TypeName::Scalar(chalk_ir::Scalar::Int(i)), empty());
+        let uint = |i| apply(chalk_ir::TypeName::Scalar(chalk_ir::Scalar::Uint(i)), empty());
+        let float = |f| apply(chalk_ir::TypeName::Scalar(chalk_ir::Scalar::Float(f)), empty());
+
+        return match self.kind {
+            Bool => apply(chalk_ir::TypeName::Scalar(chalk_ir::Scalar::Bool), empty()),
+            Char => apply(chalk_ir::TypeName::Scalar(chalk_ir::Scalar::Char), empty()),
+            Int(ty) => match ty {
+                ast::IntTy::Isize => int(chalk_ir::IntTy::Isize),
+                ast::IntTy::I8 => int(chalk_ir::IntTy::I8),
+                ast::IntTy::I16 => int(chalk_ir::IntTy::I16),
+                ast::IntTy::I32 => int(chalk_ir::IntTy::I32),
+                ast::IntTy::I64 => int(chalk_ir::IntTy::I64),
+                ast::IntTy::I128 => int(chalk_ir::IntTy::I128),
+            },
+            Uint(ty) => match ty {
+                ast::UintTy::Usize => uint(chalk_ir::UintTy::Usize),
+                ast::UintTy::U8 => uint(chalk_ir::UintTy::U8),
+                ast::UintTy::U16 => uint(chalk_ir::UintTy::U16),
+                ast::UintTy::U32 => uint(chalk_ir::UintTy::U32),
+                ast::UintTy::U64 => uint(chalk_ir::UintTy::U64),
+                ast::UintTy::U128 => uint(chalk_ir::UintTy::U128),
+            },
+            Float(ty) => match ty {
+                ast::FloatTy::F32 => float(chalk_ir::FloatTy::F32),
+                ast::FloatTy::F64 => float(chalk_ir::FloatTy::F64),
+            },
+            Adt(def, substs) => {
+                apply(struct_ty(RustDefId::Adt(def.did)), substs.lower_into(interner))
+            }
+            Foreign(_def_id) => unimplemented!(),
+            Str => apply(struct_ty(RustDefId::Str), empty()),
+            Array(ty, _) => apply(
+                struct_ty(RustDefId::Array),
+                chalk_ir::Substitution::from1(
+                    interner,
+                    chalk_ir::ParameterKind::Ty(ty.lower_into(interner)).intern(interner),
+                ),
+            ),
+            Slice(ty) => apply(
+                struct_ty(RustDefId::Slice),
+                chalk_ir::Substitution::from1(
+                    interner,
+                    chalk_ir::ParameterKind::Ty(ty.lower_into(interner)).intern(interner),
+                ),
+            ),
+            RawPtr(_) => apply(struct_ty(RustDefId::RawPtr), empty()),
+            Ref(region, ty, mutability) => apply(
+                struct_ty(RustDefId::Ref(mutability)),
+                chalk_ir::Substitution::from(
+                    interner,
+                    [
+                        chalk_ir::ParameterKind::Lifetime(region.lower_into(interner))
+                            .intern(interner),
+                        chalk_ir::ParameterKind::Ty(ty.lower_into(interner)).intern(interner),
+                    ]
+                    .iter(),
+                ),
+            ),
+            FnDef(def_id, _) => apply(struct_ty(RustDefId::FnDef(def_id)), empty()),
+            FnPtr(sig) => {
+                let (inputs_and_outputs, binders, _named_regions) =
+                    collect_bound_vars(interner, interner.tcx, &sig.inputs_and_output());
+                TyData::Function(chalk_ir::Fn {
+                    num_binders: binders.len(interner),
+                    substitution: chalk_ir::Substitution::from(
+                        interner,
+                        inputs_and_outputs.iter().map(|ty| {
+                            chalk_ir::ParameterKind::Ty(ty.lower_into(interner)).intern(interner)
+                        }),
+                    ),
+                })
+                .intern(interner)
+            }
+            Dynamic(_, _) => unimplemented!(),
+            Closure(_def_id, _) => unimplemented!(),
+            Generator(_def_id, _substs, _) => unimplemented!(),
+            GeneratorWitness(_) => unimplemented!(),
+            Never => apply(struct_ty(RustDefId::Never), empty()),
+            Tuple(substs) => {
+                apply(chalk_ir::TypeName::Tuple(substs.len()), substs.lower_into(interner))
+            }
+            Projection(proj) => TyData::Alias(proj.lower_into(interner)).intern(interner),
+            UnnormalizedProjection(_proj) => unimplemented!(),
+            Opaque(_def_id, _substs) => unimplemented!(),
+            // This should have been done eagerly prior to this, and all Params
+            // should have been substituted to placeholders
+            Param(_) => panic!("Lowering Param when not expected."),
+            Bound(db, bound) => TyData::BoundVar(chalk_ir::BoundVar::new(
+                chalk_ir::DebruijnIndex::new(db.as_u32()),
+                bound.var.index(),
+            ))
+            .intern(interner),
+            Placeholder(_placeholder) => TyData::Placeholder(chalk_ir::PlaceholderIndex {
+                ui: chalk_ir::UniverseIndex { counter: _placeholder.universe.as_usize() },
+                idx: _placeholder.name.as_usize(),
+            })
+            .intern(interner),
+            Infer(_infer) => unimplemented!(),
+            Error => unimplemented!(),
+        };
+    }
+}
+
+impl<'tcx> LowerInto<'tcx, chalk_ir::Lifetime<RustInterner<'tcx>>> for Region<'tcx> {
+    fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::Lifetime<RustInterner<'tcx>> {
+        use rustc_middle::ty::RegionKind::*;
+
+        match self {
+            ReEarlyBound(_) => {
+                panic!("Should have already been substituted.");
+            }
+            ReLateBound(db, br) => match br {
+                ty::BoundRegion::BrAnon(var) => {
+                    chalk_ir::LifetimeData::BoundVar(chalk_ir::BoundVar::new(
+                        chalk_ir::DebruijnIndex::new(db.as_u32()),
+                        *var as usize,
+                    ))
+                    .intern(interner)
+                }
+                ty::BoundRegion::BrNamed(_def_id, _name) => unimplemented!(),
+                ty::BrEnv => unimplemented!(),
+            },
+            ReFree(_) => unimplemented!(),
+            ReScope(_) => unimplemented!(),
+            ReStatic => unimplemented!(),
+            ReVar(_) => unimplemented!(),
+            RePlaceholder(placeholder_region) => {
+                chalk_ir::LifetimeData::Placeholder(chalk_ir::PlaceholderIndex {
+                    ui: chalk_ir::UniverseIndex { counter: placeholder_region.universe.index() },
+                    idx: 0,
+                })
+                .intern(interner)
+            }
+            ReEmpty(_) => unimplemented!(),
+            ReErased => unimplemented!(),
+        }
+    }
+}
+
+impl<'tcx> LowerInto<'tcx, chalk_ir::Parameter<RustInterner<'tcx>>> for GenericArg<'tcx> {
+    fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::Parameter<RustInterner<'tcx>> {
+        match self.unpack() {
+            ty::subst::GenericArgKind::Type(ty) => {
+                chalk_ir::ParameterKind::Ty(ty.lower_into(interner))
+            }
+            ty::subst::GenericArgKind::Lifetime(lifetime) => {
+                chalk_ir::ParameterKind::Lifetime(lifetime.lower_into(interner))
+            }
+            ty::subst::GenericArgKind::Const(_) => chalk_ir::ParameterKind::Ty(
+                chalk_ir::TyData::Apply(chalk_ir::ApplicationTy {
+                    name: chalk_ir::TypeName::Tuple(0),
+                    substitution: chalk_ir::Substitution::empty(interner),
+                })
+                .intern(interner),
+            ),
+        }
+        .intern(interner)
+    }
+}
+
+// We lower into an Option here since there are some predicates which Chalk
+// doesn't have a representation for yet (as a `WhereClause`), but are so common
+// that we just are accepting the unsoundness for now. The `Option` will
+// eventually be removed.
+impl<'tcx> LowerInto<'tcx, Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>
+    for ty::Predicate<'tcx>
+{
+    fn lower_into(
+        self,
+        interner: &RustInterner<'tcx>,
+    ) -> Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>> {
+        match &self {
+            Predicate::Trait(predicate, _) => {
+                let (predicate, binders, _named_regions) =
+                    collect_bound_vars(interner, interner.tcx, predicate);
+
+                Some(chalk_ir::Binders::new(
+                    binders,
+                    chalk_ir::WhereClause::Implemented(predicate.trait_ref.lower_into(interner)),
+                ))
+            }
+            Predicate::RegionOutlives(_predicate) => None,
+            Predicate::TypeOutlives(_predicate) => None,
+            Predicate::Projection(_predicate) => None,
+            Predicate::WellFormed(_ty) => None,
+
+            Predicate::ObjectSafe(..)
+            | Predicate::ClosureKind(..)
+            | Predicate::Subtype(..)
+            | Predicate::ConstEvaluatable(..) => bug!("unexpected predicate {}", &self),
+        }
+    }
+}
+
+/// To collect bound vars, we have to do two passes. In the first pass, we
+/// collect all `BoundRegion`s and `ty::Bound`s. In the second pass, we then
+/// replace `BrNamed` into `BrAnon`. The two separate passes are important,
+/// since we can only replace `BrNamed` with `BrAnon`s with indices *after* all
+/// "real" `BrAnon`s.
+///
+/// It's important to note that because of prior substitution, we may have
+/// late-bound regions, even outside of fn contexts, since this is the best way
+/// to prep types for chalk lowering.
+crate fn collect_bound_vars<'a, 'tcx, T: TypeFoldable<'tcx>>(
+    interner: &RustInterner<'tcx>,
+    tcx: TyCtxt<'tcx>,
+    ty: &'a Binder<T>,
+) -> (T, chalk_ir::ParameterKinds<RustInterner<'tcx>>, BTreeMap<DefId, u32>) {
+    let mut bound_vars_collector = BoundVarsCollector::new();
+    ty.skip_binder().visit_with(&mut bound_vars_collector);
+    let mut parameters = bound_vars_collector.parameters;
+    let named_parameters: BTreeMap<DefId, u32> = bound_vars_collector
+        .named_parameters
+        .into_iter()
+        .enumerate()
+        .map(|(i, def_id)| (def_id, (i + parameters.len()) as u32))
+        .collect();
+
+    let mut bound_var_substitutor = NamedBoundVarSubstitutor::new(tcx, &named_parameters);
+    let new_ty = ty.skip_binder().fold_with(&mut bound_var_substitutor);
+
+    for var in named_parameters.values() {
+        parameters.insert(*var, chalk_ir::ParameterKind::Lifetime(()));
+    }
+
+    (0..parameters.len()).for_each(|i| {
+        parameters.get(&(i as u32)).expect("Skipped bound var index.");
+    });
+
+    let binders = chalk_ir::ParameterKinds::from(interner, parameters.into_iter().map(|(_, v)| v));
+
+    (new_ty, binders, named_parameters)
+}
+
+crate struct BoundVarsCollector {
+    binder_index: ty::DebruijnIndex,
+    crate parameters: BTreeMap<u32, chalk_ir::ParameterKind<()>>,
+    crate named_parameters: Vec<DefId>,
+}
+
+impl BoundVarsCollector {
+    crate fn new() -> Self {
+        BoundVarsCollector {
+            binder_index: ty::INNERMOST,
+            parameters: BTreeMap::new(),
+            named_parameters: vec![],
+        }
+    }
+}
+
+impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector {
+    fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> bool {
+        self.binder_index.shift_in(1);
+        let result = t.super_visit_with(self);
+        self.binder_index.shift_out(1);
+        result
+    }
+
+    fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
+        match t.kind {
+            ty::Bound(debruijn, bound_ty) if debruijn == self.binder_index => {
+                match self.parameters.entry(bound_ty.var.as_u32()) {
+                    Entry::Vacant(entry) => {
+                        entry.insert(chalk_ir::ParameterKind::Ty(()));
+                    }
+                    Entry::Occupied(entry) => {
+                        entry.get().assert_ty_ref();
+                    }
+                }
+            }
+
+            _ => (),
+        };
+
+        t.super_visit_with(self)
+    }
+
+    fn visit_region(&mut self, r: Region<'tcx>) -> bool {
+        match r {
+            ty::ReLateBound(index, br) if *index == self.binder_index => match br {
+                ty::BoundRegion::BrNamed(def_id, _name) => {
+                    if self.named_parameters.iter().find(|d| *d == def_id).is_none() {
+                        self.named_parameters.push(*def_id);
+                    }
+                }
+
+                ty::BoundRegion::BrAnon(var) => match self.parameters.entry(*var) {
+                    Entry::Vacant(entry) => {
+                        entry.insert(chalk_ir::ParameterKind::Lifetime(()));
+                    }
+                    Entry::Occupied(entry) => {
+                        entry.get().assert_lifetime_ref();
+                    }
+                },
+
+                ty::BrEnv => unimplemented!(),
+            },
+
+            ty::ReEarlyBound(_re) => {
+                // FIXME(chalk): jackh726 - I think we should always have already
+                // substituted away `ReEarlyBound`s for `ReLateBound`s, but need to confirm.
+                unimplemented!();
+            }
+
+            _ => (),
+        };
+
+        r.super_visit_with(self)
+    }
+}
+
+/// This is used to replace `BoundRegion::BrNamed` with `BoundRegion::BrAnon`.
+/// Note: we assume that we will always have room for more bound vars. (i.e. we
+/// won't ever hit the `u32` limit in `BrAnon`s).
+struct NamedBoundVarSubstitutor<'a, 'tcx> {
+    tcx: TyCtxt<'tcx>,
+    binder_index: ty::DebruijnIndex,
+    named_parameters: &'a BTreeMap<DefId, u32>,
+}
+
+impl<'a, 'tcx> NamedBoundVarSubstitutor<'a, 'tcx> {
+    fn new(tcx: TyCtxt<'tcx>, named_parameters: &'a BTreeMap<DefId, u32>) -> Self {
+        NamedBoundVarSubstitutor { tcx, binder_index: ty::INNERMOST, named_parameters }
+    }
+}
+
+impl<'a, 'tcx> TypeFolder<'tcx> for NamedBoundVarSubstitutor<'a, 'tcx> {
+    fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
+        self.tcx
+    }
+
+    fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> Binder<T> {
+        self.binder_index.shift_in(1);
+        let result = t.super_fold_with(self);
+        self.binder_index.shift_out(1);
+        result
+    }
+
+    fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
+        t.super_fold_with(self)
+    }
+
+    fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> {
+        match r {
+            ty::ReLateBound(index, br) if *index == self.binder_index => match br {
+                ty::BoundRegion::BrNamed(def_id, _name) => {
+                    match self.named_parameters.get(def_id) {
+                        Some(idx) => {
+                            return self.tcx.mk_region(RegionKind::ReLateBound(
+                                *index,
+                                BoundRegion::BrAnon(*idx),
+                            ));
+                        }
+                        None => panic!("Missing `BrNamed`."),
+                    }
+                }
+                ty::BrEnv => unimplemented!(),
+                ty::BoundRegion::BrAnon(_) => {}
+            },
+            _ => (),
+        };
+
+        r.super_fold_with(self)
+    }
+}
+
+/// Used to substitute `Param`s with placeholders. We do this since Chalk
+/// have a notion of `Param`s.
+crate struct ParamsSubstitutor<'tcx> {
+    tcx: TyCtxt<'tcx>,
+    binder_index: ty::DebruijnIndex,
+    list: Vec<rustc_middle::ty::ParamTy>,
+    crate params: rustc_data_structures::fx::FxHashMap<usize, rustc_middle::ty::ParamTy>,
+    crate named_regions: BTreeMap<DefId, u32>,
+}
+
+impl<'tcx> ParamsSubstitutor<'tcx> {
+    crate fn new(tcx: TyCtxt<'tcx>) -> Self {
+        ParamsSubstitutor {
+            tcx,
+            binder_index: ty::INNERMOST,
+            list: vec![],
+            params: rustc_data_structures::fx::FxHashMap::default(),
+            named_regions: BTreeMap::default(),
+        }
+    }
+}
+
+impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> {
+    fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
+        self.tcx
+    }
+
+    fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> Binder<T> {
+        self.binder_index.shift_in(1);
+        let result = t.super_fold_with(self);
+        self.binder_index.shift_out(1);
+        result
+    }
+
+    fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
+        match t.kind {
+            // FIXME(chalk): currently we convert params to placeholders starting at
+            // index `0`. To support placeholders, we'll actually need to do a
+            // first pass to collect placeholders. Then we can insert params after.
+            ty::Placeholder(_) => unimplemented!(),
+            ty::Param(param) => match self.list.iter().position(|r| r == &param) {
+                Some(_idx) => self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
+                    universe: ty::UniverseIndex::from_usize(0),
+                    name: ty::BoundVar::from_usize(_idx),
+                })),
+                None => {
+                    self.list.push(param);
+                    let idx = self.list.len() - 1;
+                    self.params.insert(idx, param);
+                    self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
+                        universe: ty::UniverseIndex::from_usize(0),
+                        name: ty::BoundVar::from_usize(idx),
+                    }))
+                }
+            },
+
+            _ => t.super_fold_with(self),
+        }
+    }
+
+    fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> {
+        match r {
+            // FIXME(chalk) - jackh726 - this currently isn't hit in any tests.
+            // This covers any region variables in a goal, right?
+            ty::ReEarlyBound(_re) => match self.named_regions.get(&_re.def_id) {
+                Some(idx) => self.tcx.mk_region(RegionKind::ReLateBound(
+                    self.binder_index,
+                    BoundRegion::BrAnon(*idx),
+                )),
+                None => {
+                    let idx = self.named_regions.len() as u32;
+                    self.named_regions.insert(_re.def_id, idx);
+                    self.tcx.mk_region(RegionKind::ReLateBound(
+                        self.binder_index,
+                        BoundRegion::BrAnon(idx),
+                    ))
+                }
+            },
+
+            _ => r.super_fold_with(self),
+        }
+    }
+}
diff --git a/src/librustc_traits/chalk/mod.rs b/src/librustc_traits/chalk/mod.rs
new file mode 100644
index 00000000000..4e635b9db09
--- /dev/null
+++ b/src/librustc_traits/chalk/mod.rs
@@ -0,0 +1,227 @@
+//! Calls `chalk-solve` to solve a `ty::Predicate`
+//!
+//! In order to call `chalk-solve`, this file must convert a
+//! `ChalkCanonicalGoal` into a Chalk ucanonical goal. It then calls Chalk, and
+//! converts the answer back into rustc solution.
+
+crate mod db;
+crate mod lowering;
+
+use rustc_data_structures::fx::FxHashMap;
+
+use rustc_index::vec::IndexVec;
+
+use rustc_middle::infer::canonical::{CanonicalTyVarKind, CanonicalVarKind};
+use rustc_middle::traits::ChalkRustInterner;
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::subst::GenericArg;
+use rustc_middle::ty::{
+    self, Bound, BoundVar, ParamTy, Region, RegionKind, Ty, TyCtxt, TypeFoldable,
+};
+
+use rustc_infer::infer::canonical::{
+    Canonical, CanonicalVarValues, Certainty, QueryRegionConstraints, QueryResponse,
+};
+use rustc_infer::traits::{self, ChalkCanonicalGoal, ChalkRustDefId as RustDefId};
+
+use crate::chalk::db::RustIrDatabase as ChalkRustIrDatabase;
+use crate::chalk::lowering::{LowerInto, ParamsSubstitutor};
+
+use chalk_solve::Solution;
+
+crate fn provide(p: &mut Providers<'_>) {
+    *p = Providers { evaluate_goal, ..*p };
+}
+
+crate fn evaluate_goal<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    obligation: ChalkCanonicalGoal<'tcx>,
+) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, ()>>, traits::query::NoSolution> {
+    let interner = ChalkRustInterner { tcx };
+
+    // Chalk doesn't have a notion of `Params`, so instead we use placeholders.
+    let mut params_substitutor = ParamsSubstitutor::new(tcx);
+    let obligation = obligation.fold_with(&mut params_substitutor);
+    let _params: FxHashMap<usize, ParamTy> = params_substitutor.params;
+    let max_universe = obligation.max_universe.index();
+
+    let _lowered_goal: chalk_ir::UCanonical<
+        chalk_ir::InEnvironment<chalk_ir::Goal<ChalkRustInterner<'tcx>>>,
+    > = chalk_ir::UCanonical {
+        canonical: chalk_ir::Canonical {
+            binders: chalk_ir::CanonicalVarKinds::from(
+                &interner,
+                obligation.variables.iter().map(|v| match v.kind {
+                    CanonicalVarKind::PlaceholderTy(_ty) => unimplemented!(),
+                    CanonicalVarKind::PlaceholderRegion(_ui) => unimplemented!(),
+                    CanonicalVarKind::Ty(ty) => match ty {
+                        CanonicalTyVarKind::General(ui) => {
+                            chalk_ir::ParameterKind::Ty(chalk_ir::UniverseIndex {
+                                counter: ui.index(),
+                            })
+                        }
+                        CanonicalTyVarKind::Int | CanonicalTyVarKind::Float => {
+                            // FIXME(chalk) - this is actually really important
+                            // These variable kinds put some limits on the
+                            // types that can be substituted (floats or ints).
+                            // While it's unclear exactly the design here, we
+                            // probably want some way to "register" these.
+                            chalk_ir::ParameterKind::Ty(chalk_ir::UniverseIndex::root())
+                        }
+                    },
+                    CanonicalVarKind::Region(ui) => {
+                        chalk_ir::ParameterKind::Lifetime(chalk_ir::UniverseIndex {
+                            counter: ui.index(),
+                        })
+                    }
+                    CanonicalVarKind::Const(_ui) => unimplemented!(),
+                    CanonicalVarKind::PlaceholderConst(_pc) => unimplemented!(),
+                }),
+            ),
+            value: obligation.value.lower_into(&interner),
+        },
+        universes: max_universe + 1,
+    };
+
+    let solver_choice = chalk_solve::SolverChoice::SLG { max_size: 32, expected_answers: None };
+    let mut solver = solver_choice.into_solver::<ChalkRustInterner<'tcx>>();
+
+    let db = ChalkRustIrDatabase { tcx, interner };
+    let solution = solver.solve(&db, &_lowered_goal);
+
+    // Ideally, the code to convert *back* to rustc types would live close to
+    // the code to convert *from* rustc types. Right now though, we don't
+    // really need this and so it's really minimal.
+    // Right now, we also treat a `Unique` solution the same as
+    // `Ambig(Definite)`. This really isn't right.
+    let make_solution = |_subst: chalk_ir::Substitution<_>| {
+        let mut var_values: IndexVec<BoundVar, GenericArg<'tcx>> = IndexVec::new();
+        _subst.parameters(&interner).iter().for_each(|p| {
+            // FIXME(chalk): we should move this elsewhere, since this is
+            // essentially inverse of lowering a `GenericArg`.
+            let _data = p.data(&interner);
+            match _data {
+                chalk_ir::ParameterKind::Ty(_t) => {
+                    use chalk_ir::TyData;
+                    use rustc_ast::ast;
+
+                    let _data = _t.data(&interner);
+                    let kind = match _data {
+                        TyData::Apply(_application_ty) => match _application_ty.name {
+                            chalk_ir::TypeName::Struct(_struct_id) => match _struct_id.0 {
+                                RustDefId::Array => unimplemented!(),
+                                RustDefId::Slice => unimplemented!(),
+                                _ => unimplemented!(),
+                            },
+                            chalk_ir::TypeName::Scalar(scalar) => match scalar {
+                                chalk_ir::Scalar::Bool => ty::Bool,
+                                chalk_ir::Scalar::Char => ty::Char,
+                                chalk_ir::Scalar::Int(int_ty) => match int_ty {
+                                    chalk_ir::IntTy::Isize => ty::Int(ast::IntTy::Isize),
+                                    chalk_ir::IntTy::I8 => ty::Int(ast::IntTy::I8),
+                                    chalk_ir::IntTy::I16 => ty::Int(ast::IntTy::I16),
+                                    chalk_ir::IntTy::I32 => ty::Int(ast::IntTy::I32),
+                                    chalk_ir::IntTy::I64 => ty::Int(ast::IntTy::I64),
+                                    chalk_ir::IntTy::I128 => ty::Int(ast::IntTy::I128),
+                                },
+                                chalk_ir::Scalar::Uint(int_ty) => match int_ty {
+                                    chalk_ir::UintTy::Usize => ty::Uint(ast::UintTy::Usize),
+                                    chalk_ir::UintTy::U8 => ty::Uint(ast::UintTy::U8),
+                                    chalk_ir::UintTy::U16 => ty::Uint(ast::UintTy::U16),
+                                    chalk_ir::UintTy::U32 => ty::Uint(ast::UintTy::U32),
+                                    chalk_ir::UintTy::U64 => ty::Uint(ast::UintTy::U64),
+                                    chalk_ir::UintTy::U128 => ty::Uint(ast::UintTy::U128),
+                                },
+                                chalk_ir::Scalar::Float(float_ty) => match float_ty {
+                                    chalk_ir::FloatTy::F32 => ty::Float(ast::FloatTy::F32),
+                                    chalk_ir::FloatTy::F64 => ty::Float(ast::FloatTy::F64),
+                                },
+                            },
+                            chalk_ir::TypeName::Tuple(_size) => unimplemented!(),
+                            chalk_ir::TypeName::OpaqueType(_ty) => unimplemented!(),
+                            chalk_ir::TypeName::AssociatedType(_assoc_ty) => unimplemented!(),
+                            chalk_ir::TypeName::Error => unimplemented!(),
+                        },
+                        TyData::Placeholder(_placeholder) => {
+                            unimplemented!();
+                        }
+                        TyData::Alias(_alias_ty) => unimplemented!(),
+                        TyData::Function(_quantified_ty) => unimplemented!(),
+                        TyData::BoundVar(_bound) => Bound(
+                            ty::DebruijnIndex::from_usize(_bound.debruijn.depth() as usize),
+                            ty::BoundTy {
+                                var: ty::BoundVar::from_usize(_bound.index),
+                                kind: ty::BoundTyKind::Anon,
+                            },
+                        ),
+                        TyData::InferenceVar(_) => unimplemented!(),
+                        TyData::Dyn(_) => unimplemented!(),
+                    };
+                    let _ty: Ty<'_> = tcx.mk_ty(kind);
+                    let _arg: GenericArg<'_> = _ty.into();
+                    var_values.push(_arg);
+                }
+                chalk_ir::ParameterKind::Lifetime(_l) => {
+                    let _data = _l.data(&interner);
+                    let _lifetime: Region<'_> = match _data {
+                        chalk_ir::LifetimeData::BoundVar(_var) => {
+                            tcx.mk_region(RegionKind::ReLateBound(
+                                rustc_middle::ty::DebruijnIndex::from_usize(
+                                    _var.debruijn.depth() as usize
+                                ),
+                                rustc_middle::ty::BoundRegion::BrAnon(_var.index as u32),
+                            ))
+                        }
+                        chalk_ir::LifetimeData::InferenceVar(_var) => unimplemented!(),
+                        chalk_ir::LifetimeData::Placeholder(_index) => unimplemented!(),
+                        chalk_ir::LifetimeData::Phantom(_, _) => unimplemented!(),
+                    };
+                    let _arg: GenericArg<'_> = _lifetime.into();
+                    var_values.push(_arg);
+                }
+            }
+        });
+        let sol = Canonical {
+            max_universe: ty::UniverseIndex::from_usize(0),
+            variables: obligation.variables.clone(),
+            value: QueryResponse {
+                var_values: CanonicalVarValues { var_values },
+                region_constraints: QueryRegionConstraints::default(),
+                certainty: Certainty::Proven,
+                value: (),
+            },
+        };
+        &*tcx.arena.alloc(sol)
+    };
+    solution
+        .map(|s| match s {
+            Solution::Unique(_subst) => {
+                // FIXME(chalk): handle constraints
+                assert!(_subst.value.constraints.is_empty());
+                make_solution(_subst.value.subst)
+            }
+            Solution::Ambig(_guidance) => {
+                match _guidance {
+                    chalk_solve::Guidance::Definite(_subst) => make_solution(_subst.value),
+                    chalk_solve::Guidance::Suggested(_) => unimplemented!(),
+                    chalk_solve::Guidance::Unknown => {
+                        // chalk_fulfill doesn't use the var_values here, so
+                        // let's just ignore that
+                        let sol = Canonical {
+                            max_universe: ty::UniverseIndex::from_usize(0),
+                            variables: obligation.variables.clone(),
+                            value: QueryResponse {
+                                var_values: CanonicalVarValues { var_values: IndexVec::new() }
+                                    .make_identity(tcx),
+                                region_constraints: QueryRegionConstraints::default(),
+                                certainty: Certainty::Ambiguous,
+                                value: (),
+                            },
+                        };
+                        &*tcx.arena.alloc(sol)
+                    }
+                }
+            }
+        })
+        .ok_or(traits::query::NoSolution)
+}
diff --git a/src/librustc_traits/lib.rs b/src/librustc_traits/lib.rs
index e0533b11ecf..f3dfdffda41 100644
--- a/src/librustc_traits/lib.rs
+++ b/src/librustc_traits/lib.rs
@@ -12,6 +12,7 @@ extern crate log;
 #[macro_use]
 extern crate rustc_middle;
 
+mod chalk;
 mod dropck_outlives;
 mod evaluate_obligation;
 mod implied_outlives_bounds;
@@ -25,6 +26,7 @@ pub fn provide(p: &mut Providers<'_>) {
     dropck_outlives::provide(p);
     evaluate_obligation::provide(p);
     implied_outlives_bounds::provide(p);
+    chalk::provide(p);
     normalize_projection_ty::provide(p);
     normalize_erasing_regions::provide(p);
     type_op::provide(p);
diff --git a/src/librustc_ty/ty.rs b/src/librustc_ty/ty.rs
index c5ead053a7f..6add099e75b 100644
--- a/src/librustc_ty/ty.rs
+++ b/src/librustc_ty/ty.rs
@@ -262,8 +262,11 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
     // are any errors at that point, so after type checking you can be
     // sure that this will succeed without errors anyway.
 
-    let unnormalized_env =
-        ty::ParamEnv::new(tcx.intern_predicates(&predicates), traits::Reveal::UserFacing, None);
+    let unnormalized_env = ty::ParamEnv::new(
+        tcx.intern_predicates(&predicates),
+        traits::Reveal::UserFacing,
+        tcx.sess.opts.debugging_opts.chalk.then_some(def_id),
+    );
 
     let body_id = def_id
         .as_local()
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index cd6cd94b143..6529d784ad4 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -8,7 +8,6 @@
 use crate::collect::PlaceholderHirTyCollector;
 use crate::middle::resolve_lifetime as rl;
 use crate::require_c_abi_if_c_variadic;
-use rustc_ast::ast;
 use rustc_ast::util::lev_distance::find_best_match_for_name;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::ErrorReported;
@@ -27,7 +26,7 @@ use rustc_middle::ty::{GenericParamDef, GenericParamDefKind};
 use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, LATE_BOUND_LIFETIME_ARGUMENTS};
 use rustc_session::parse::feature_err;
 use rustc_session::Session;
-use rustc_span::symbol::sym;
+use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::{MultiSpan, Span, DUMMY_SP};
 use rustc_target::spec::abi;
 use rustc_trait_selection::traits;
@@ -114,7 +113,7 @@ pub enum SizedByDefault {
 }
 
 struct ConvertedBinding<'a, 'tcx> {
-    item_name: ast::Ident,
+    item_name: Ident,
     kind: ConvertedBindingKind<'a, 'tcx>,
     span: Span,
 }
@@ -1183,11 +1182,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         )
     }
 
-    fn trait_defines_associated_type_named(
-        &self,
-        trait_def_id: DefId,
-        assoc_name: ast::Ident,
-    ) -> bool {
+    fn trait_defines_associated_type_named(&self, trait_def_id: DefId, assoc_name: Ident) -> bool {
         self.tcx()
             .associated_items(trait_def_id)
             .find_by_name_and_kind(self.tcx(), assoc_name, ty::AssocKind::Type, trait_def_id)
@@ -1938,7 +1933,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         span: Span,
         type_str: &str,
         trait_str: &str,
-        name: ast::Name,
+        name: Symbol,
     ) {
         let mut err = struct_span_err!(self.tcx().sess, span, E0223, "ambiguous associated type");
         if let (Some(_), Ok(snippet)) = (
@@ -1969,7 +1964,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
     fn find_bound_for_assoc_item(
         &self,
         ty_param_def_id: LocalDefId,
-        assoc_name: ast::Ident,
+        assoc_name: Ident,
         span: Span,
     ) -> Result<ty::PolyTraitRef<'tcx>, ErrorReported> {
         let tcx = self.tcx();
@@ -2006,7 +2001,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         &self,
         all_candidates: impl Fn() -> I,
         ty_param_name: impl Fn() -> String,
-        assoc_name: ast::Ident,
+        assoc_name: Ident,
         span: Span,
         is_equality: impl Fn() -> Option<String>,
     ) -> Result<ty::PolyTraitRef<'tcx>, ErrorReported>
@@ -2124,7 +2119,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         &self,
         all_candidates: impl Fn() -> I,
         ty_param_name: &str,
-        assoc_name: ast::Ident,
+        assoc_name: Ident,
         span: Span,
     ) where
         I: Iterator<Item = ty::PolyTraitRef<'tcx>>,
diff --git a/src/librustc_typeck/check/autoderef.rs b/src/librustc_typeck/check/autoderef.rs
index 2bb00553232..ae6c1738da7 100644
--- a/src/librustc_typeck/check/autoderef.rs
+++ b/src/librustc_typeck/check/autoderef.rs
@@ -1,7 +1,6 @@
 use super::method::MethodCallee;
 use super::{FnCtxt, Needs, PlaceOp};
 
-use rustc_ast::ast::Ident;
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_infer::infer::{InferCtxt, InferOk};
@@ -9,6 +8,7 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref};
 use rustc_middle::ty::{self, TraitRef, Ty, TyCtxt, WithConstness};
 use rustc_middle::ty::{ToPredicate, TypeFoldable};
 use rustc_session::DiagnosticMessageId;
+use rustc_span::symbol::Ident;
 use rustc_span::Span;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
 use rustc_trait_selection::traits::{self, TraitEngine};
diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs
index 0d254412203..52ddacc1c4b 100644
--- a/src/librustc_typeck/check/callee.rs
+++ b/src/librustc_typeck/check/callee.rs
@@ -3,7 +3,6 @@ use super::method::MethodCallee;
 use super::{Expectation, FnCtxt, Needs, TupleArgumentsFlag};
 use crate::type_error_struct;
 
-use rustc_ast::ast::Ident;
 use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
 use rustc_hir as hir;
 use rustc_hir::def::Res;
@@ -15,6 +14,7 @@ use rustc_middle::ty::adjustment::{
 };
 use rustc_middle::ty::subst::SubstsRef;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
+use rustc_span::symbol::Ident;
 use rustc_span::Span;
 use rustc_target::spec::abi;
 
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index 92ddfbff824..71e1b32aeaa 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -37,7 +37,7 @@ use rustc_middle::ty::TypeFoldable;
 use rustc_middle::ty::{AdtKind, Visibility};
 use rustc_span::hygiene::DesugaringKind;
 use rustc_span::source_map::Span;
-use rustc_span::symbol::{kw, sym, Symbol};
+use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_trait_selection::traits::{self, ObligationCauseCode};
 
 use std::fmt::Display;
@@ -1411,7 +1411,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         find_best_match_for_name(names, field, None)
     }
 
-    fn available_field_names(&self, variant: &'tcx ty::VariantDef) -> Vec<ast::Name> {
+    fn available_field_names(&self, variant: &'tcx ty::VariantDef) -> Vec<Symbol> {
         variant
             .fields
             .iter()
@@ -1426,7 +1426,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             .collect()
     }
 
-    fn name_series_display(&self, names: Vec<ast::Name>) -> String {
+    fn name_series_display(&self, names: Vec<Symbol>) -> String {
         // dynamic limit, to never omit just one field
         let limit = if names.len() == 6 { 6 } else { 5 };
         let mut display =
@@ -1443,7 +1443,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expr: &'tcx hir::Expr<'tcx>,
         needs: Needs,
         base: &'tcx hir::Expr<'tcx>,
-        field: ast::Ident,
+        field: Ident,
     ) -> Ty<'tcx> {
         let expr_t = self.check_expr_with_needs(base, needs);
         let expr_t = self.structurally_resolved_type(base.span, expr_t);
@@ -1522,7 +1522,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn ban_nonexisting_field(
         &self,
-        field: ast::Ident,
+        field: Ident,
         base: &'tcx hir::Expr<'tcx>,
         expr: &'tcx hir::Expr<'tcx>,
         expr_t: Ty<'tcx>,
@@ -1560,7 +1560,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         &self,
         expr: &hir::Expr<'_>,
         expr_t: Ty<'tcx>,
-        field: ast::Ident,
+        field: Ident,
         base_did: DefId,
     ) {
         let struct_path = self.tcx().def_path_str(base_did);
@@ -1589,7 +1589,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         err.emit();
     }
 
-    fn ban_take_value_of_method(&self, expr: &hir::Expr<'_>, expr_t: Ty<'tcx>, field: ast::Ident) {
+    fn ban_take_value_of_method(&self, expr: &hir::Expr<'_>, expr_t: Ty<'tcx>, field: Ident) {
         let mut err = type_error_struct!(
             self.tcx().sess,
             field.span,
@@ -1636,7 +1636,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         &self,
         err: &mut DiagnosticBuilder<'_>,
         def: &'tcx ty::AdtDef,
-        field: ast::Ident,
+        field: Ident,
     ) {
         if let Some(suggested_field_name) =
             Self::suggest_field_name(def.non_enum_variant(), &field.as_str(), vec![])
@@ -1665,7 +1665,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         err: &mut DiagnosticBuilder<'_>,
         expr: &hir::Expr<'_>,
         base: &hir::Expr<'_>,
-        field: ast::Ident,
+        field: Ident,
         len: &ty::Const<'tcx>,
     ) {
         if let (Some(len), Ok(user_index)) =
@@ -1689,7 +1689,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         err: &mut DiagnosticBuilder<'_>,
         expr: &hir::Expr<'_>,
         base: &hir::Expr<'_>,
-        field: ast::Ident,
+        field: Ident,
     ) {
         if let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span) {
             let msg = format!("`{}` is a raw pointer; try dereferencing it", base);
diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs
index ae2061a2e3f..a254aecf07b 100644
--- a/src/librustc_typeck/check/method/mod.rs
+++ b/src/librustc_typeck/check/method/mod.rs
@@ -11,7 +11,6 @@ pub use self::CandidateSource::*;
 pub use self::MethodError::*;
 
 use crate::check::FnCtxt;
-use rustc_ast::ast;
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::{Applicability, DiagnosticBuilder};
 use rustc_hir as hir;
@@ -22,6 +21,7 @@ use rustc_middle::ty::subst::Subst;
 use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
 use rustc_middle::ty::GenericParamDefKind;
 use rustc_middle::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TypeFoldable, WithConstness};
+use rustc_span::symbol::Ident;
 use rustc_span::Span;
 use rustc_trait_selection::traits;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
@@ -104,7 +104,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// Determines whether the type `self_ty` supports a method name `method_name` or not.
     pub fn method_exists(
         &self,
-        method_name: ast::Ident,
+        method_name: Ident,
         self_ty: Ty<'tcx>,
         call_expr_id: hir::HirId,
         allow_private: bool,
@@ -133,7 +133,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         &self,
         err: &mut DiagnosticBuilder<'a>,
         msg: &str,
-        method_name: ast::Ident,
+        method_name: Ident,
         self_ty: Ty<'tcx>,
         call_expr: &hir::Expr<'_>,
     ) {
@@ -260,7 +260,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub fn lookup_probe(
         &self,
         span: Span,
-        method_name: ast::Ident,
+        method_name: Ident,
         self_ty: Ty<'tcx>,
         call_expr: &'tcx hir::Expr<'tcx>,
         scope: ProbeScope,
@@ -290,7 +290,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub fn lookup_method_in_trait(
         &self,
         span: Span,
-        m_name: ast::Ident,
+        m_name: Ident,
         trait_def_id: DefId,
         self_ty: Ty<'tcx>,
         opt_input_types: Option<&[Ty<'tcx>]>,
@@ -414,7 +414,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub fn resolve_ufcs(
         &self,
         span: Span,
-        method_name: ast::Ident,
+        method_name: Ident,
         self_ty: Ty<'tcx>,
         expr_id: hir::HirId,
     ) -> Result<(DefKind, DefId), MethodError<'tcx>> {
@@ -478,7 +478,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub fn associated_item(
         &self,
         def_id: DefId,
-        item_name: ast::Ident,
+        item_name: Ident,
         ns: Namespace,
     ) -> Option<ty::AssocItem> {
         self.tcx
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index 03e32c21a54..7f1d77e5b97 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -28,7 +28,7 @@ use rustc_middle::ty::{
 };
 use rustc_session::config::nightly_options;
 use rustc_session::lint;
-use rustc_span::{symbol::Symbol, Span, DUMMY_SP};
+use rustc_span::{symbol::Ident, Span, Symbol, DUMMY_SP};
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
 use rustc_trait_selection::traits::query::method_autoderef::MethodAutoderefBadTy;
 use rustc_trait_selection::traits::query::method_autoderef::{
@@ -55,7 +55,7 @@ struct ProbeContext<'a, 'tcx> {
     fcx: &'a FnCtxt<'a, 'tcx>,
     span: Span,
     mode: Mode,
-    method_name: Option<ast::Ident>,
+    method_name: Option<Ident>,
     return_type: Option<Ty<'tcx>>,
 
     /// This is the OriginalQueryValues for the steps queries
@@ -268,7 +268,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         &self,
         span: Span,
         mode: Mode,
-        item_name: ast::Ident,
+        item_name: Ident,
         is_suggestion: IsSuggestion,
         self_ty: Ty<'tcx>,
         scope_expr_id: hir::HirId,
@@ -295,7 +295,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         &'a self,
         span: Span,
         mode: Mode,
-        method_name: Option<ast::Ident>,
+        method_name: Option<Ident>,
         return_type: Option<Ty<'tcx>>,
         is_suggestion: IsSuggestion,
         self_ty: Ty<'tcx>,
@@ -518,7 +518,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         fcx: &'a FnCtxt<'a, 'tcx>,
         span: Span,
         mode: Mode,
-        method_name: Option<ast::Ident>,
+        method_name: Option<Ident>,
         return_type: Option<Ty<'tcx>>,
         orig_steps_var_values: OriginalQueryValues<'tcx>,
         steps: Lrc<Vec<CandidateStep<'tcx>>>,
@@ -978,7 +978,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         Ok(())
     }
 
-    fn candidate_method_names(&self) -> Vec<ast::Ident> {
+    fn candidate_method_names(&self) -> Vec<Ident> {
         let mut set = FxHashSet::default();
         let mut names: Vec<_> = self
             .inherent_candidates
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 857cc972559..cf26c94418e 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -2,7 +2,6 @@
 //! found or is otherwise invalid.
 
 use crate::check::FnCtxt;
-use rustc_ast::ast;
 use rustc_ast::util::lev_distance;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
@@ -18,7 +17,7 @@ use rustc_middle::ty::print::with_crate_prefix;
 use rustc_middle::ty::{
     self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
 };
-use rustc_span::symbol::kw;
+use rustc_span::symbol::{kw, Ident};
 use rustc_span::{source_map, FileName, Span};
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
 use rustc_trait_selection::traits::Obligation;
@@ -72,7 +71,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         &self,
         span: Span,
         rcvr_ty: Ty<'tcx>,
-        item_name: ast::Ident,
+        item_name: Ident,
         source: SelfSource<'b>,
         error: MethodError<'tcx>,
         args: Option<&'tcx [hir::Expr<'tcx>]>,
@@ -923,7 +922,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         err: &mut DiagnosticBuilder<'_>,
         span: Span,
         rcvr_ty: Ty<'tcx>,
-        item_name: ast::Ident,
+        item_name: Ident,
         source: SelfSource<'b>,
         valid_out_of_scope_traits: Vec<DefId>,
         unsatisfied_predicates: &[(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>)],
@@ -1378,7 +1377,7 @@ impl intravisit::Visitor<'tcx> for UsePlacementFinder<'tcx> {
 }
 
 fn print_disambiguation_help(
-    item_name: ast::Ident,
+    item_name: Ident,
     args: Option<&'tcx [hir::Expr<'tcx>]>,
     err: &mut DiagnosticBuilder<'_>,
     trait_name: String,
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index bff1ca2433a..956e09ec52b 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3718,14 +3718,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         None
     }
 
-    fn resolve_place_op(&self, op: PlaceOp, is_mut: bool) -> (Option<DefId>, ast::Ident) {
+    fn resolve_place_op(&self, op: PlaceOp, is_mut: bool) -> (Option<DefId>, Ident) {
         let (tr, name) = match (op, is_mut) {
             (PlaceOp::Deref, false) => (self.tcx.lang_items().deref_trait(), sym::deref),
             (PlaceOp::Deref, true) => (self.tcx.lang_items().deref_mut_trait(), sym::deref_mut),
             (PlaceOp::Index, false) => (self.tcx.lang_items().index_trait(), sym::index),
             (PlaceOp::Index, true) => (self.tcx.lang_items().index_mut_trait(), sym::index_mut),
         };
-        (tr, ast::Ident::with_dummy_span(name))
+        (tr, Ident::with_dummy_span(name))
     }
 
     fn try_overloaded_place_op(
@@ -4824,19 +4824,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
-    fn get_parent_fn_decl(
-        &self,
-        blk_id: hir::HirId,
-    ) -> Option<(&'tcx hir::FnDecl<'tcx>, ast::Ident)> {
+    fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident)> {
         let parent = self.tcx.hir().get(self.tcx.hir().get_parent_item(blk_id));
         self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident))
     }
 
     /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
-    fn get_node_fn_decl(
-        &self,
-        node: Node<'tcx>,
-    ) -> Option<(&'tcx hir::FnDecl<'tcx>, ast::Ident, bool)> {
+    fn get_node_fn_decl(&self, node: Node<'tcx>) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident, bool)> {
         match node {
             Node::Item(&hir::Item { ident, kind: hir::ItemKind::Fn(ref sig, ..), .. }) => {
                 // This is less than ideal, it will not suggest a return type span on any
diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs
index e6cbc8ab723..00ff2af82e3 100644
--- a/src/librustc_typeck/check/op.rs
+++ b/src/librustc_typeck/check/op.rs
@@ -2,7 +2,6 @@
 
 use super::method::MethodCallee;
 use super::{FnCtxt, Needs};
-use rustc_ast::ast::Ident;
 use rustc_errors::{self, struct_span_err, Applicability, DiagnosticBuilder};
 use rustc_hir as hir;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
@@ -11,6 +10,7 @@ use rustc_middle::ty::adjustment::{
 };
 use rustc_middle::ty::TyKind::{Adt, Array, Char, FnDef, Never, Ref, Str, Tuple, Uint};
 use rustc_middle::ty::{self, suggest_constraining_type_param, Ty, TyCtxt, TypeFoldable};
+use rustc_span::symbol::Ident;
 use rustc_span::Span;
 use rustc_trait_selection::infer::InferCtxtExt;
 
diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index 8e109efbcb5..8a10427260e 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -13,6 +13,7 @@ use rustc_middle::ty::subst::GenericArg;
 use rustc_middle::ty::{self, BindingMode, Ty, TypeFoldable};
 use rustc_span::hygiene::DesugaringKind;
 use rustc_span::source_map::{Span, Spanned};
+use rustc_span::symbol::Ident;
 use rustc_trait_selection::traits::{ObligationCause, Pattern};
 
 use std::cmp;
@@ -1133,7 +1134,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         err.emit();
     }
 
-    fn error_field_already_bound(&self, span: Span, ident: ast::Ident, other_field: Span) {
+    fn error_field_already_bound(&self, span: Span, ident: Ident, other_field: Span) {
         struct_span_err!(
             self.tcx.sess,
             span,
@@ -1149,8 +1150,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn error_inexistent_fields(
         &self,
         kind_name: &str,
-        inexistent_fields: &[ast::Ident],
-        unmentioned_fields: &mut Vec<ast::Ident>,
+        inexistent_fields: &[Ident],
+        unmentioned_fields: &mut Vec<Ident>,
         variant: &ty::VariantDef,
     ) {
         let tcx = self.tcx;
@@ -1225,7 +1226,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn error_unmentioned_fields(
         &self,
         span: Span,
-        unmentioned_fields: &[ast::Ident],
+        unmentioned_fields: &[Ident],
         variant: &ty::VariantDef,
     ) {
         let field_names = if unmentioned_fields.len() == 1 {
diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs
index 55802c140bc..6aa8242193d 100644
--- a/src/librustc_typeck/check/upvar.rs
+++ b/src/librustc_typeck/check/upvar.rs
@@ -35,7 +35,6 @@ use super::FnCtxt;
 use crate::expr_use_visitor as euv;
 use crate::mem_categorization as mc;
 use crate::mem_categorization::PlaceBase;
-use rustc_ast::ast;
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
@@ -43,7 +42,7 @@ use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_infer::infer::UpvarRegion;
 use rustc_middle::ty::{self, Ty, TyCtxt, UpvarSubsts};
-use rustc_span::Span;
+use rustc_span::{Span, Symbol};
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub fn closure_analyze(&self, body: &'tcx hir::Body<'tcx>) {
@@ -261,7 +260,7 @@ struct InferBorrowKind<'a, 'tcx> {
 
     // If we modified `current_closure_kind`, this field contains a `Some()` with the
     // variable access that caused us to do so.
-    current_origin: Option<(Span, ast::Name)>,
+    current_origin: Option<(Span, Symbol)>,
 
     // For each upvar that we access, we track the minimal kind of
     // access we need (ref, ref mut, move, etc).
@@ -415,7 +414,7 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {
         closure_id: LocalDefId,
         new_kind: ty::ClosureKind,
         upvar_span: Span,
-        var_name: ast::Name,
+        var_name: Symbol,
     ) {
         debug!(
             "adjust_closure_kind(closure_id={:?}, new_kind={:?}, upvar_span={:?}, var_name={})",
@@ -480,6 +479,6 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> {
     }
 }
 
-fn var_name(tcx: TyCtxt<'_>, var_hir_id: hir::HirId) -> ast::Name {
+fn var_name(tcx: TyCtxt<'_>, var_hir_id: hir::HirId) -> Symbol {
     tcx.hir().name(var_hir_id)
 }
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index e82e40503e0..b79ac50da8f 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -15,7 +15,7 @@ use rustc_middle::ty::{
     self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
 };
 use rustc_session::parse::feature_err;
-use rustc_span::symbol::sym;
+use rustc_span::symbol::{sym, Symbol};
 use rustc_span::Span;
 use rustc_trait_selection::opaque_types::may_define_opaque_type;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
@@ -1226,7 +1226,7 @@ fn check_variances_for_type_defn<'tcx>(
     }
 }
 
-fn report_bivariance(tcx: TyCtxt<'_>, span: Span, param_name: ast::Name) {
+fn report_bivariance(tcx: TyCtxt<'_>, span: Span, param_name: Symbol) {
     let mut err = error_392(tcx, span, param_name);
 
     let suggested_marker_id = tcx.lang_items().phantom_data();
@@ -1368,7 +1368,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 }
 
-fn error_392(tcx: TyCtxt<'_>, span: Span, param_name: ast::Name) -> DiagnosticBuilder<'_> {
+fn error_392(tcx: TyCtxt<'_>, span: Span, param_name: Symbol) -> DiagnosticBuilder<'_> {
     let mut err =
         struct_span_err!(tcx.sess, span, E0392, "parameter `{}` is never used", param_name);
     err.span_label(span, "unused parameter");
diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs
index ce1538bfa49..dfe86aecbf7 100644
--- a/src/librustc_typeck/check_unused.rs
+++ b/src/librustc_typeck/check_unused.rs
@@ -1,4 +1,3 @@
-use rustc_ast::ast;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
@@ -6,7 +5,7 @@ use rustc_hir::def_id::{DefId, DefIdSet, LOCAL_CRATE};
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::lint;
-use rustc_span::Span;
+use rustc_span::{Span, Symbol};
 
 pub fn check_crate(tcx: TyCtxt<'_>) {
     let mut used_trait_imports = DefIdSet::default();
@@ -202,7 +201,7 @@ struct ExternCrateToLint {
     /// if `Some`, then this is renamed (`extern crate orig_name as
     /// crate_name`), and -- perhaps surprisingly -- this stores the
     /// *original* name (`item.name` will contain the new name)
-    orig_name: Option<ast::Name>,
+    orig_name: Option<Symbol>,
 
     /// if `false`, the original name started with `_`, so we shouldn't lint
     /// about it going unused (but we should still emit idiom lints).
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 0fad3284598..854bd03b264 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -19,7 +19,7 @@ use crate::check::intrinsic::intrinsic_operation_unsafety;
 use crate::constrained_generic_params as cgp;
 use crate::middle::resolve_lifetime as rl;
 use rustc_ast::ast;
-use rustc_ast::ast::{Ident, MetaItemKind};
+use rustc_ast::ast::MetaItemKind;
 use rustc_attr::{list_contains_name, mark_used, InlineAttr, OptimizeAttr};
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -42,7 +42,7 @@ use rustc_middle::ty::{self, AdtKind, Const, ToPolyTraitRef, Ty, TyCtxt};
 use rustc_middle::ty::{ReprOptions, ToPredicate, WithConstness};
 use rustc_session::lint;
 use rustc_session::parse::feature_err;
-use rustc_span::symbol::{kw, sym, Symbol};
+use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{Span, DUMMY_SP};
 use rustc_target::spec::abi;
 use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamName;
@@ -813,7 +813,7 @@ fn convert_variant(
     adt_kind: ty::AdtKind,
     parent_did: LocalDefId,
 ) -> ty::VariantDef {
-    let mut seen_fields: FxHashMap<ast::Ident, Span> = Default::default();
+    let mut seen_fields: FxHashMap<Ident, Span> = Default::default();
     let hir_id = tcx.hir().as_local_hir_id(variant_did.unwrap_or(parent_did));
     let fields = def
         .fields()
diff --git a/src/librustdoc/clean/cfg/tests.rs b/src/librustdoc/clean/cfg/tests.rs
index 3b26742e716..716263393ba 100644
--- a/src/librustdoc/clean/cfg/tests.rs
+++ b/src/librustdoc/clean/cfg/tests.rs
@@ -3,7 +3,7 @@ use super::*;
 use rustc_ast::ast::*;
 use rustc_ast::attr;
 use rustc_ast::with_default_globals;
-use rustc_span::symbol::Symbol;
+use rustc_span::symbol::{Ident, Symbol};
 use rustc_span::DUMMY_SP;
 
 fn word_cfg(s: &str) -> Cfg {
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index cd098936ed6..4bf3649dcc2 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -12,6 +12,7 @@ use rustc_metadata::creader::LoadedMacro;
 use rustc_middle::ty;
 use rustc_mir::const_eval::is_min_const_fn;
 use rustc_span::hygiene::MacroKind;
+use rustc_span::symbol::Symbol;
 use rustc_span::Span;
 
 use crate::clean::{self, GetDefId, ToSource, TypeKind};
@@ -37,7 +38,7 @@ type Attrs<'hir> = rustc_middle::ty::Attributes<'hir>;
 pub fn try_inline(
     cx: &DocContext<'_>,
     res: Res,
-    name: ast::Name,
+    name: Symbol,
     attrs: Option<Attrs<'_>>,
     visited: &mut FxHashSet<DefId>,
 ) -> Option<Vec<clean::Item>> {
@@ -515,7 +516,7 @@ fn build_static(cx: &DocContext<'_>, did: DefId, mutable: bool) -> clean::Static
     }
 }
 
-fn build_macro(cx: &DocContext<'_>, did: DefId, name: ast::Name) -> clean::ItemEnum {
+fn build_macro(cx: &DocContext<'_>, did: DefId, name: Symbol) -> clean::ItemEnum {
     let imported_from = cx.tcx.original_crate_name(did.krate);
     match cx.enter_resolver(|r| r.cstore().load_macro_untracked(did, cx.sess())) {
         LoadedMacro::MacroDef(def, _) => {
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 55c32e917f2..8cd9ab41aa4 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -9,7 +9,7 @@ mod simplify;
 pub mod types;
 pub mod utils;
 
-use rustc_ast::ast::{self, Ident};
+use rustc_ast::ast;
 use rustc_attr as attr;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir as hir;
@@ -24,7 +24,7 @@ use rustc_middle::ty::subst::InternalSubsts;
 use rustc_middle::ty::{self, AdtKind, Lift, Ty, TyCtxt};
 use rustc_mir::const_eval::is_min_const_fn;
 use rustc_span::hygiene::MacroKind;
-use rustc_span::symbol::{kw, sym};
+use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{self, Pos};
 use rustc_typeck::hir_ty_to_ty;
 
@@ -921,7 +921,7 @@ impl Clean<Item> for doctree::Function<'_> {
     }
 }
 
-impl<'a> Clean<Arguments> for (&'a [hir::Ty<'a>], &'a [ast::Ident]) {
+impl<'a> Clean<Arguments> for (&'a [hir::Ty<'a>], &'a [Ident]) {
     fn clean(&self, cx: &DocContext<'_>) -> Arguments {
         Arguments {
             values: self
@@ -2006,7 +2006,7 @@ impl Clean<String> for Ident {
     }
 }
 
-impl Clean<String> for ast::Name {
+impl Clean<String> for Symbol {
     #[inline]
     fn clean(&self, _: &DocContext<'_>) -> String {
         self.to_string()
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 0a682857b18..8bf811877a6 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -8,7 +8,7 @@ use std::rc::Rc;
 use std::sync::Arc;
 use std::{slice, vec};
 
-use rustc_ast::ast::{self, AttrStyle, Ident};
+use rustc_ast::ast::{self, AttrStyle};
 use rustc_ast::attr;
 use rustc_ast::util::comments::strip_doc_comment_decoration;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -21,7 +21,7 @@ use rustc_index::vec::IndexVec;
 use rustc_middle::middle::stability;
 use rustc_span::hygiene::MacroKind;
 use rustc_span::source_map::DUMMY_SP;
-use rustc_span::symbol::{sym, Symbol};
+use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::{self, FileName};
 use rustc_target::abi::VariantIdx;
 use rustc_target::spec::abi::Abi;
diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs
index 41b8e66d265..5b138327427 100644
--- a/src/librustdoc/doctree.rs
+++ b/src/librustdoc/doctree.rs
@@ -3,15 +3,14 @@
 pub use self::StructType::*;
 
 use rustc_ast::ast;
-use rustc_ast::ast::Name;
 use rustc_span::hygiene::MacroKind;
-use rustc_span::{self, Span};
+use rustc_span::{self, Span, Symbol};
 
 use rustc_hir as hir;
 use rustc_hir::def_id::CrateNum;
 
 pub struct Module<'hir> {
-    pub name: Option<Name>,
+    pub name: Option<Symbol>,
     pub attrs: &'hir [ast::Attribute],
     pub where_outer: Span,
     pub where_inner: Span,
@@ -39,7 +38,7 @@ pub struct Module<'hir> {
 
 impl Module<'hir> {
     pub fn new(
-        name: Option<Name>,
+        name: Option<Symbol>,
         attrs: &'hir [ast::Attribute],
         vis: &'hir hir::Visibility<'hir>,
     ) -> Module<'hir> {
@@ -86,7 +85,7 @@ pub struct Struct<'hir> {
     pub vis: &'hir hir::Visibility<'hir>,
     pub id: hir::HirId,
     pub struct_type: StructType,
-    pub name: Name,
+    pub name: Symbol,
     pub generics: &'hir hir::Generics<'hir>,
     pub attrs: &'hir [ast::Attribute],
     pub fields: &'hir [hir::StructField<'hir>],
@@ -97,7 +96,7 @@ pub struct Union<'hir> {
     pub vis: &'hir hir::Visibility<'hir>,
     pub id: hir::HirId,
     pub struct_type: StructType,
-    pub name: Name,
+    pub name: Symbol,
     pub generics: &'hir hir::Generics<'hir>,
     pub attrs: &'hir [ast::Attribute],
     pub fields: &'hir [hir::StructField<'hir>],
@@ -111,11 +110,11 @@ pub struct Enum<'hir> {
     pub attrs: &'hir [ast::Attribute],
     pub id: hir::HirId,
     pub whence: Span,
-    pub name: Name,
+    pub name: Symbol,
 }
 
 pub struct Variant<'hir> {
-    pub name: Name,
+    pub name: Symbol,
     pub id: hir::HirId,
     pub attrs: &'hir [ast::Attribute],
     pub def: &'hir hir::VariantData<'hir>,
@@ -126,7 +125,7 @@ pub struct Function<'hir> {
     pub decl: &'hir hir::FnDecl<'hir>,
     pub attrs: &'hir [ast::Attribute],
     pub id: hir::HirId,
-    pub name: Name,
+    pub name: Symbol,
     pub vis: &'hir hir::Visibility<'hir>,
     pub header: hir::FnHeader,
     pub whence: Span,
@@ -137,7 +136,7 @@ pub struct Function<'hir> {
 pub struct Typedef<'hir> {
     pub ty: &'hir hir::Ty<'hir>,
     pub gen: &'hir hir::Generics<'hir>,
-    pub name: Name,
+    pub name: Symbol,
     pub id: hir::HirId,
     pub attrs: &'hir [ast::Attribute],
     pub whence: Span,
@@ -146,7 +145,7 @@ pub struct Typedef<'hir> {
 
 pub struct OpaqueTy<'hir> {
     pub opaque_ty: &'hir hir::OpaqueTy<'hir>,
-    pub name: Name,
+    pub name: Symbol,
     pub id: hir::HirId,
     pub attrs: &'hir [ast::Attribute],
     pub whence: Span,
@@ -158,7 +157,7 @@ pub struct Static<'hir> {
     pub type_: &'hir hir::Ty<'hir>,
     pub mutability: hir::Mutability,
     pub expr: hir::BodyId,
-    pub name: Name,
+    pub name: Symbol,
     pub attrs: &'hir [ast::Attribute],
     pub vis: &'hir hir::Visibility<'hir>,
     pub id: hir::HirId,
@@ -168,7 +167,7 @@ pub struct Static<'hir> {
 pub struct Constant<'hir> {
     pub type_: &'hir hir::Ty<'hir>,
     pub expr: hir::BodyId,
-    pub name: Name,
+    pub name: Symbol,
     pub attrs: &'hir [ast::Attribute],
     pub vis: &'hir hir::Visibility<'hir>,
     pub id: hir::HirId,
@@ -178,7 +177,7 @@ pub struct Constant<'hir> {
 pub struct Trait<'hir> {
     pub is_auto: hir::IsAuto,
     pub unsafety: hir::Unsafety,
-    pub name: Name,
+    pub name: Symbol,
     pub items: Vec<&'hir hir::TraitItem<'hir>>,
     pub generics: &'hir hir::Generics<'hir>,
     pub bounds: &'hir [hir::GenericBound<'hir>],
@@ -189,7 +188,7 @@ pub struct Trait<'hir> {
 }
 
 pub struct TraitAlias<'hir> {
-    pub name: Name,
+    pub name: Symbol,
     pub generics: &'hir hir::Generics<'hir>,
     pub bounds: &'hir [hir::GenericBound<'hir>],
     pub attrs: &'hir [ast::Attribute],
@@ -217,7 +216,7 @@ pub struct Impl<'hir> {
 pub struct ForeignItem<'hir> {
     pub vis: &'hir hir::Visibility<'hir>,
     pub id: hir::HirId,
-    pub name: Name,
+    pub name: Symbol,
     pub kind: &'hir hir::ForeignItemKind<'hir>,
     pub attrs: &'hir [ast::Attribute],
     pub whence: Span,
@@ -226,17 +225,17 @@ pub struct ForeignItem<'hir> {
 // For Macro we store the DefId instead of the NodeId, since we also create
 // these imported macro_rules (which only have a DUMMY_NODE_ID).
 pub struct Macro<'hir> {
-    pub name: Name,
+    pub name: Symbol,
     pub hid: hir::HirId,
     pub def_id: hir::def_id::DefId,
     pub attrs: &'hir [ast::Attribute],
     pub whence: Span,
     pub matchers: Vec<Span>,
-    pub imported_from: Option<Name>,
+    pub imported_from: Option<Symbol>,
 }
 
 pub struct ExternCrate<'hir> {
-    pub name: Name,
+    pub name: Symbol,
     pub cnum: CrateNum,
     pub path: Option<String>,
     pub vis: &'hir hir::Visibility<'hir>,
@@ -245,7 +244,7 @@ pub struct ExternCrate<'hir> {
 }
 
 pub struct Import<'hir> {
-    pub name: Name,
+    pub name: Symbol,
     pub id: hir::HirId,
     pub vis: &'hir hir::Visibility<'hir>,
     pub attrs: &'hir [ast::Attribute],
@@ -255,10 +254,10 @@ pub struct Import<'hir> {
 }
 
 pub struct ProcMacro<'hir> {
-    pub name: Name,
+    pub name: Symbol,
     pub id: hir::HirId,
     pub kind: MacroKind,
-    pub helpers: Vec<Name>,
+    pub helpers: Vec<Symbol>,
     pub attrs: &'hir [ast::Attribute],
     pub whence: Span,
 }
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 43b641c7fe6..fbdb538cd87 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -1,4 +1,4 @@
-use rustc_ast::ast::{self, Ident};
+use rustc_ast::ast;
 use rustc_errors::Applicability;
 use rustc_expand::base::SyntaxExtensionKind;
 use rustc_feature::UnstableFeatures;
@@ -12,7 +12,7 @@ use rustc_hir::def_id::DefId;
 use rustc_middle::ty;
 use rustc_resolve::ParentScope;
 use rustc_session::lint;
-use rustc_span::symbol::Symbol;
+use rustc_span::symbol::{Ident, Symbol};
 use rustc_span::DUMMY_SP;
 
 use std::ops::Range;
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index acfcfe9d015..d2a950027cf 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -11,7 +11,7 @@ use rustc_middle::middle::privacy::AccessLevel;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::hygiene::MacroKind;
 use rustc_span::source_map::Spanned;
-use rustc_span::symbol::{kw, sym};
+use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{self, Span};
 
 use std::mem;
@@ -85,7 +85,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
     fn visit_variant_data(
         &mut self,
         item: &'tcx hir::Item,
-        name: ast::Name,
+        name: Symbol,
         sd: &'tcx hir::VariantData,
         generics: &'tcx hir::Generics,
     ) -> Struct<'tcx> {
@@ -106,7 +106,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
     fn visit_union_data(
         &mut self,
         item: &'tcx hir::Item,
-        name: ast::Name,
+        name: Symbol,
         sd: &'tcx hir::VariantData,
         generics: &'tcx hir::Generics,
     ) -> Union<'tcx> {
@@ -127,7 +127,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
     fn visit_enum_def(
         &mut self,
         it: &'tcx hir::Item,
-        name: ast::Name,
+        name: Symbol,
         def: &'tcx hir::EnumDef,
         generics: &'tcx hir::Generics,
     ) -> Enum<'tcx> {
@@ -157,7 +157,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         &mut self,
         om: &mut Module<'tcx>,
         item: &'tcx hir::Item,
-        name: ast::Name,
+        name: Symbol,
         decl: &'tcx hir::FnDecl,
         header: hir::FnHeader,
         generics: &'tcx hir::Generics,
@@ -234,7 +234,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         vis: &'tcx hir::Visibility,
         id: hir::HirId,
         m: &'tcx hir::Mod<'tcx>,
-        name: Option<ast::Name>,
+        name: Option<Symbol>,
     ) -> Module<'tcx> {
         let mut om = Module::new(name, attrs, vis);
         om.where_outer = span;
@@ -264,7 +264,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         &mut self,
         id: hir::HirId,
         res: Res,
-        renamed: Option<ast::Ident>,
+        renamed: Option<Ident>,
         glob: bool,
         om: &mut Module<'tcx>,
         please_inline: bool,
@@ -375,12 +375,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         ret
     }
 
-    fn visit_item(
-        &mut self,
-        item: &'tcx hir::Item,
-        renamed: Option<ast::Ident>,
-        om: &mut Module<'tcx>,
-    ) {
+    fn visit_item(&mut self, item: &'tcx hir::Item, renamed: Option<Ident>, om: &mut Module<'tcx>) {
         debug!("visiting item {:?}", item);
         let ident = renamed.unwrap_or(item.ident);
 
@@ -593,7 +588,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
     fn visit_foreign_item(
         &mut self,
         item: &'tcx hir::ForeignItem,
-        renamed: Option<ast::Ident>,
+        renamed: Option<Ident>,
         om: &mut Module<'tcx>,
     ) {
         // If inlining we only want to include public functions.
@@ -612,11 +607,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
     }
 
     // Convert each `exported_macro` into a doc item.
-    fn visit_local_macro(
-        &self,
-        def: &'tcx hir::MacroDef,
-        renamed: Option<ast::Name>,
-    ) -> Macro<'tcx> {
+    fn visit_local_macro(&self, def: &'tcx hir::MacroDef, renamed: Option<Symbol>) -> Macro<'tcx> {
         debug!("visit_local_macro: {}", def.ident);
         let tts = def.ast.body.inner_tokens().trees().collect::<Vec<_>>();
         // Extract the spans of all matchers. They represent the "interface" of the macro.
diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp
index e1d75418243..84bde9a52f7 100644
--- a/src/rustllvm/PassWrapper.cpp
+++ b/src/rustllvm/PassWrapper.cpp
@@ -447,7 +447,8 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
     bool Singlethread,
     bool AsmComments,
     bool EmitStackSizeSection,
-    bool RelaxELFRelocations) {
+    bool RelaxELFRelocations,
+    bool UseInitArray) {
 
   auto OptLevel = fromRust(RustOptLevel);
   auto RM = fromRust(RustReloc);
@@ -473,6 +474,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
   Options.MCOptions.PreserveAsmComments = AsmComments;
   Options.MCOptions.ABIName = ABIStr;
   Options.RelaxELFRelocations = RelaxELFRelocations;
+  Options.UseInitArray = UseInitArray;
 
   if (TrapUnreachable) {
     // Tell LLVM to codegen `unreachable` into an explicit trap instruction.
diff --git a/src/test/run-fail/bug-811.rs b/src/test/run-fail/bug-811.rs
deleted file mode 100644
index e36ec0f5901..00000000000
--- a/src/test/run-fail/bug-811.rs
+++ /dev/null
@@ -1,24 +0,0 @@
-// error-pattern:quux
-
-use std::marker::PhantomData;
-
-fn test00_start(ch: chan_t<isize>, message: isize) {
-    send(ch, message);
-}
-
-type task_id = isize;
-type port_id = isize;
-
-struct chan_t<T> {
-    task: task_id,
-    port: port_id,
-    marker: PhantomData<*mut T>,
-}
-
-fn send<T: Send>(_ch: chan_t<T>, _data: T) {
-    panic!();
-}
-
-fn main() {
-    panic!("quux");
-}
diff --git a/src/test/run-fail/overflowing-lsh-1.rs b/src/test/run-fail/overflowing-lsh-1.rs
deleted file mode 100644
index 977cfea0fe0..00000000000
--- a/src/test/run-fail/overflowing-lsh-1.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-// error-pattern:thread 'main' panicked at 'attempt to shift left with overflow'
-// compile-flags: -C debug-assertions
-
-#![warn(arithmetic_overflow)]
-#![warn(const_err)]
-
-fn main() {
-    let _x = 1_i32 << 32;
-}
diff --git a/src/test/run-fail/overflowing-lsh-2.rs b/src/test/run-fail/overflowing-lsh-2.rs
deleted file mode 100644
index 3517dacde3a..00000000000
--- a/src/test/run-fail/overflowing-lsh-2.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-// error-pattern:thread 'main' panicked at 'attempt to shift left with overflow'
-// compile-flags: -C debug-assertions
-
-#![warn(arithmetic_overflow)]
-#![warn(const_err)]
-
-fn main() {
-    let _x = 1 << -1;
-}
diff --git a/src/test/run-fail/overflowing-lsh-3.rs b/src/test/run-fail/overflowing-lsh-3.rs
deleted file mode 100644
index 4a575c3fa7f..00000000000
--- a/src/test/run-fail/overflowing-lsh-3.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-// error-pattern:thread 'main' panicked at 'attempt to shift left with overflow'
-// compile-flags: -C debug-assertions
-
-#![warn(arithmetic_overflow)]
-#![warn(const_err)]
-
-fn main() {
-    let _x = 1_u64 << 64;
-}
diff --git a/src/test/run-fail/overflowing-rsh-1.rs b/src/test/run-fail/overflowing-rsh-1.rs
deleted file mode 100644
index 4592b2b6260..00000000000
--- a/src/test/run-fail/overflowing-rsh-1.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-// error-pattern:thread 'main' panicked at 'attempt to shift right with overflow'
-// compile-flags: -C debug-assertions
-
-#![warn(arithmetic_overflow)]
-#![warn(const_err)]
-
-fn main() {
-    let _x = -1_i32 >> 32;
-}
diff --git a/src/test/run-fail/overflowing-rsh-2.rs b/src/test/run-fail/overflowing-rsh-2.rs
deleted file mode 100644
index 066267b770d..00000000000
--- a/src/test/run-fail/overflowing-rsh-2.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-// error-pattern:thread 'main' panicked at 'attempt to shift right with overflow'
-// compile-flags: -C debug-assertions
-
-#![warn(arithmetic_overflow)]
-#![warn(const_err)]
-
-fn main() {
-    let _x = -1_i32 >> -1;
-}
diff --git a/src/test/run-fail/overflowing-rsh-3.rs b/src/test/run-fail/overflowing-rsh-3.rs
deleted file mode 100644
index 67e78482866..00000000000
--- a/src/test/run-fail/overflowing-rsh-3.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-// error-pattern:thread 'main' panicked at 'attempt to shift right with overflow'
-// compile-flags: -C debug-assertions
-
-#![warn(arithmetic_overflow)]
-#![warn(const_err)]
-
-fn main() {
-    let _x = -1_i64 >> 64;
-}
diff --git a/src/test/run-fail/overflowing-rsh-5.rs b/src/test/run-fail/overflowing-rsh-5.rs
deleted file mode 100644
index 20ef324a82a..00000000000
--- a/src/test/run-fail/overflowing-rsh-5.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-// error-pattern:thread 'main' panicked at 'attempt to shift right with overflow'
-// compile-flags: -C debug-assertions
-
-#![warn(arithmetic_overflow)]
-#![warn(const_err)]
-
-fn main() {
-    let _n = 1i64 >> [64][0];
-}
diff --git a/src/test/run-fail/overflowing-rsh-6.rs b/src/test/run-fail/overflowing-rsh-6.rs
deleted file mode 100644
index 589a98bab04..00000000000
--- a/src/test/run-fail/overflowing-rsh-6.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-// error-pattern:thread 'main' panicked at 'attempt to shift right with overflow'
-// compile-flags: -C debug-assertions
-
-#![warn(arithmetic_overflow)]
-#![warn(const_err)]
-#![feature(const_indexing)]
-
-fn main() {
-    let _n = 1i64 >> [64][0];
-}
diff --git a/src/test/run-fail/panic-macro-any.rs b/src/test/run-fail/panic-macro-any.rs
deleted file mode 100644
index 72d42e5b799..00000000000
--- a/src/test/run-fail/panic-macro-any.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-// error-pattern:panicked at 'Box<Any>'
-
-#![feature(box_syntax)]
-
-fn main() {
-    panic!(box 413 as Box<::std::any::Any + Send>);
-}
diff --git a/src/test/run-fail/unwind-unique.rs b/src/test/run-fail/unwind-unique.rs
deleted file mode 100644
index 7b761faad95..00000000000
--- a/src/test/run-fail/unwind-unique.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-// error-pattern:fail
-
-fn failfn() {
-    panic!();
-}
-
-fn main() {
-    Box::new(0);
-    failfn();
-}
diff --git a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
index 365ae301c0f..a3d31d25774 100644
--- a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
+++ b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
@@ -32,6 +32,7 @@ use rustc_parse::new_parser_from_source_str;
 use rustc_session::parse::ParseSess;
 use rustc_span::source_map::{Spanned, DUMMY_SP, FileName};
 use rustc_span::source_map::FilePathMapping;
+use rustc_span::symbol::Ident;
 use rustc_ast::ast::*;
 use rustc_ast::mut_visit::{self, MutVisitor, visit_clobber};
 use rustc_ast::ptr::P;
diff --git a/src/test/run-fail/bounds-check-no-overflow.rs b/src/test/ui/array-slice-vec/bounds-check-no-overflow.rs
index 3943f87f7fe..3caf5f44995 100644
--- a/src/test/run-fail/bounds-check-no-overflow.rs
+++ b/src/test/ui/array-slice-vec/bounds-check-no-overflow.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:index out of bounds
+// ignore-emscripten no processes
 
 use std::usize;
 use std::mem::size_of;
diff --git a/src/test/run-fail/dst-raw-slice.rs b/src/test/ui/array-slice-vec/dst-raw-slice.rs
index 2575de7cc58..371d16f093a 100644
--- a/src/test/run-fail/dst-raw-slice.rs
+++ b/src/test/ui/array-slice-vec/dst-raw-slice.rs
@@ -1,5 +1,9 @@
 // Test bounds checking for DST raw slices
+
+// run-fail
 // error-pattern:index out of bounds
+// ignore-emscripten no processes
+
 #[allow(unconditional_panic)]
 fn main() {
     let a: *const [_] = &[1, 2, 3];
diff --git a/src/test/run-fail/binop-fail-3.rs b/src/test/ui/binop/binop-fail-3.rs
index a7696fffda0..49f635e0c11 100644
--- a/src/test/run-fail/binop-fail-3.rs
+++ b/src/test/ui/binop/binop-fail-3.rs
@@ -1,9 +1,11 @@
+// run-fail
 // error-pattern:quux
+// ignore-emscripten no processes
+
 fn foo() -> ! {
     panic!("quux");
 }
 
-#[allow(resolve_trait_on_defaulted_unit)]
 fn main() {
     foo() == foo(); // these types wind up being defaulted to ()
 }
diff --git a/src/test/run-fail/binop-panic.rs b/src/test/ui/binop/binop-panic.rs
index dba5cecc67e..44cdfffeeb7 100644
--- a/src/test/run-fail/binop-panic.rs
+++ b/src/test/ui/binop/binop-panic.rs
@@ -1,8 +1,12 @@
+// run-fail
 // error-pattern:quux
+// ignore-emscripten no processes
+
 fn my_err(s: String) -> ! {
     println!("{}", s);
     panic!("quux");
 }
+
 fn main() {
     3_usize == my_err("bye".to_string());
 }
diff --git a/src/test/run-fail/borrowck-local-borrow.rs b/src/test/ui/borrowck/borrowck-local-borrow.rs
index d07f76b6252..ea4589338c4 100644
--- a/src/test/run-fail/borrowck-local-borrow.rs
+++ b/src/test/ui/borrowck/borrowck-local-borrow.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:panic 1
+// ignore-emscripten no processes
 
 // revisions: migrate mir
 //[mir]compile-flags: -Z borrowck=mir
diff --git a/src/test/ui/chalkify/basic.rs b/src/test/ui/chalkify/basic.rs
new file mode 100644
index 00000000000..dbd60fc8bb1
--- /dev/null
+++ b/src/test/ui/chalkify/basic.rs
@@ -0,0 +1,12 @@
+// check-pass
+// compile-flags: -Z chalk
+
+trait Foo {}
+
+struct Bar {}
+
+impl Foo for Bar {}
+
+fn main() -> () {
+    let _ = Bar {};
+}
diff --git a/src/test/ui/chalkify/builtin-copy-clone.rs b/src/test/ui/chalkify/builtin-copy-clone.rs
new file mode 100644
index 00000000000..d403514b553
--- /dev/null
+++ b/src/test/ui/chalkify/builtin-copy-clone.rs
@@ -0,0 +1,44 @@
+// run-pass
+// compile-flags: -Z chalk
+
+// Test that `Clone` is correctly implemented for builtin types.
+
+#[derive(Copy, Clone)]
+struct S(i32);
+
+fn test_clone<T: Clone>(arg: T) {
+    let _ = arg.clone();
+}
+
+fn test_copy<T: Copy>(arg: T) {
+    let _ = arg;
+    let _ = arg;
+}
+
+fn test_copy_clone<T: Copy + Clone>(arg: T) {
+    test_copy(arg);
+    test_clone(arg);
+}
+
+fn foo() { }
+
+fn main() {
+    test_copy_clone(foo);
+    let f: fn() = foo;
+    test_copy_clone(f);
+    // FIXME: add closures when they're considered WF
+    test_copy_clone([1; 56]);
+    test_copy_clone((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1));
+    test_copy_clone((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, true, 'a', 1.1));
+    test_copy_clone(());
+    test_copy_clone(((1, 1), (1, 1, 1), (1.1, 1, 1, 'a'), ()));
+
+    let a = (
+        (S(1), S(0)),
+        (
+            (S(0), S(0), S(1)),
+            S(0)
+        )
+    );
+    test_copy_clone(a);
+}
diff --git a/src/test/ui/chalkify/chalk_initial_program.rs b/src/test/ui/chalkify/chalk_initial_program.rs
new file mode 100644
index 00000000000..df25bad622b
--- /dev/null
+++ b/src/test/ui/chalkify/chalk_initial_program.rs
@@ -0,0 +1,16 @@
+// compile-flags: -Z chalk
+
+trait Foo { }
+
+impl Foo for i32 { }
+
+impl Foo for u32 { }
+
+fn gimme<F: Foo>() { }
+
+// Note: this also tests that `std::process::Termination` is implemented for `()`.
+fn main() {
+    gimme::<i32>();
+    gimme::<u32>();
+    gimme::<f32>(); //~ERROR the trait bound `f32: Foo` is not satisfied
+}
diff --git a/src/test/ui/chalkify/chalk_initial_program.stderr b/src/test/ui/chalkify/chalk_initial_program.stderr
new file mode 100644
index 00000000000..f2e13a6a469
--- /dev/null
+++ b/src/test/ui/chalkify/chalk_initial_program.stderr
@@ -0,0 +1,12 @@
+error[E0277]: the trait bound `f32: Foo` is not satisfied
+  --> $DIR/chalk_initial_program.rs:15:13
+   |
+LL | fn gimme<F: Foo>() { }
+   |             --- required by this bound in `gimme`
+...
+LL |     gimme::<f32>();
+   |             ^^^ the trait `Foo` is not implemented for `f32`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/chalkify/generic_impls.rs b/src/test/ui/chalkify/generic_impls.rs
new file mode 100644
index 00000000000..d70c6f8055d
--- /dev/null
+++ b/src/test/ui/chalkify/generic_impls.rs
@@ -0,0 +1,18 @@
+// compile-flags: -Z chalk
+
+trait Foo { }
+
+impl<T> Foo for (T, u32) { }
+
+fn gimme<F: Foo>() { }
+
+fn foo<T>() {
+    gimme::<(T, u32)>();
+    gimme::<(Option<T>, u32)>();
+    gimme::<(Option<T>, f32)>(); //~ ERROR
+}
+
+fn main() {
+    gimme::<(i32, u32)>();
+    gimme::<(i32, f32)>(); //~ ERROR
+}
diff --git a/src/test/ui/chalkify/generic_impls.stderr b/src/test/ui/chalkify/generic_impls.stderr
new file mode 100644
index 00000000000..4ac57a2f13f
--- /dev/null
+++ b/src/test/ui/chalkify/generic_impls.stderr
@@ -0,0 +1,27 @@
+error[E0277]: the trait bound `(std::option::Option<T>, f32): Foo` is not satisfied
+  --> $DIR/generic_impls.rs:12:13
+   |
+LL | fn gimme<F: Foo>() { }
+   |             --- required by this bound in `gimme`
+...
+LL |     gimme::<(Option<T>, f32)>();
+   |             ^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `(std::option::Option<T>, f32)`
+   |
+   = help: the following implementations were found:
+             <(T, u32) as Foo>
+
+error[E0277]: the trait bound `(i32, f32): Foo` is not satisfied
+  --> $DIR/generic_impls.rs:17:13
+   |
+LL | fn gimme<F: Foo>() { }
+   |             --- required by this bound in `gimme`
+...
+LL |     gimme::<(i32, f32)>();
+   |             ^^^^^^^^^^ the trait `Foo` is not implemented for `(i32, f32)`
+   |
+   = help: the following implementations were found:
+             <(T, u32) as Foo>
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/chalkify/impl_wf.rs b/src/test/ui/chalkify/impl_wf.rs
new file mode 100644
index 00000000000..8aa87642292
--- /dev/null
+++ b/src/test/ui/chalkify/impl_wf.rs
@@ -0,0 +1,47 @@
+// compile-flags: -Z chalk
+
+trait Foo: Sized { }
+
+trait Bar {
+    type Item: Foo;
+}
+
+impl Foo for i32 { }
+
+// FIXME(chalk): blocked on better handling of builtin traits for non-struct
+// application types (or a workaround)
+/*
+impl Foo for str { }
+//^ ERROR the size for values of type `str` cannot be known at compilation time
+*/
+
+// Implicit `T: Sized` bound.
+impl<T> Foo for Option<T> { }
+
+impl Bar for () {
+    type Item = i32;
+}
+
+impl<T> Bar for Option<T> {
+    type Item = Option<T>;
+}
+
+// FIXME(chalk): the ordering of these two errors differs between CI and local
+// We need to figure out why its non-deterministic
+/*
+impl Bar for f32 {
+//^ ERROR the trait bound `f32: Foo` is not satisfied
+    type Item = f32;
+    //^ ERROR the trait bound `f32: Foo` is not satisfied
+}
+*/
+
+trait Baz<U: ?Sized> where U: Foo { }
+
+impl Baz<i32> for i32 { }
+
+impl Baz<f32> for f32 { }
+//~^ ERROR the trait bound `f32: Foo` is not satisfied
+
+fn main() {
+}
diff --git a/src/test/ui/chalkify/impl_wf.stderr b/src/test/ui/chalkify/impl_wf.stderr
new file mode 100644
index 00000000000..befd688741c
--- /dev/null
+++ b/src/test/ui/chalkify/impl_wf.stderr
@@ -0,0 +1,12 @@
+error[E0277]: the trait bound `f32: Foo` is not satisfied
+  --> $DIR/impl_wf.rs:43:6
+   |
+LL | trait Baz<U: ?Sized> where U: Foo { }
+   |                               --- required by this bound in `Baz`
+...
+LL | impl Baz<f32> for f32 { }
+   |      ^^^^^^^^ the trait `Foo` is not implemented for `f32`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/chalkify/inherent_impl.rs b/src/test/ui/chalkify/inherent_impl.rs
new file mode 100644
index 00000000000..44e120c1eeb
--- /dev/null
+++ b/src/test/ui/chalkify/inherent_impl.rs
@@ -0,0 +1,42 @@
+// run-pass
+// compile-flags: -Z chalk
+
+trait Foo { }
+
+impl Foo for i32 { }
+
+struct S<T: Foo> {
+    x: T,
+}
+
+fn only_foo<T: Foo>(_x: &T) { }
+
+impl<T> S<T> {
+    // Test that we have the correct environment inside an inherent method.
+    fn dummy_foo(&self) {
+        only_foo(&self.x)
+    }
+}
+
+trait Bar { }
+impl Bar for u32 { }
+
+fn only_bar<T: Bar>() { }
+
+impl<T> S<T> {
+    // Test that the environment of `dummy_bar` adds up with the environment
+    // of the inherent impl.
+    fn dummy_bar<U: Bar>(&self) {
+        only_foo(&self.x);
+        only_bar::<U>();
+    }
+}
+
+fn main() {
+    let s = S {
+        x: 5,
+    };
+
+    s.dummy_foo();
+    s.dummy_bar::<u32>();
+}
diff --git a/src/test/ui/chalkify/inherent_impl_min.rs b/src/test/ui/chalkify/inherent_impl_min.rs
new file mode 100644
index 00000000000..774c46e401c
--- /dev/null
+++ b/src/test/ui/chalkify/inherent_impl_min.rs
@@ -0,0 +1,27 @@
+// run-pass
+// compile-flags: -Z chalk
+
+trait Foo { }
+
+impl Foo for i32 { }
+
+struct S<T: Foo> {
+    x: T,
+}
+
+fn only_foo<T: Foo>(_x: &T) { }
+
+impl<T> S<T> {
+    // Test that we have the correct environment inside an inherent method.
+    fn dummy_foo(&self) {
+        only_foo(&self.x)
+    }
+}
+
+fn main() {
+    let s = S {
+        x: 5,
+    };
+
+    s.dummy_foo();
+}
diff --git a/src/test/ui/chalkify/lower_env1.rs b/src/test/ui/chalkify/lower_env1.rs
new file mode 100644
index 00000000000..e3c75695921
--- /dev/null
+++ b/src/test/ui/chalkify/lower_env1.rs
@@ -0,0 +1,14 @@
+// check-pass
+// compile-flags: -Z chalk
+
+#![allow(dead_code)]
+
+trait Foo { }
+
+trait Bar where Self: Foo { }
+
+fn bar<T: Bar + ?Sized>() {
+}
+
+fn main() {
+}
diff --git a/src/test/ui/chalkify/lower_env2.rs b/src/test/ui/chalkify/lower_env2.rs
new file mode 100644
index 00000000000..b5432ce0e30
--- /dev/null
+++ b/src/test/ui/chalkify/lower_env2.rs
@@ -0,0 +1,16 @@
+// check-pass
+// compile-flags: -Z chalk
+
+#![allow(dead_code)]
+
+trait Foo { }
+
+struct S<'a, T: ?Sized> where T: Foo {
+    data: &'a T,
+}
+
+fn bar<T: Foo>(_x: S<'_, T>) { // note that we have an implicit `T: Sized` bound
+}
+
+fn main() {
+}
diff --git a/src/test/ui/chalkify/lower_env3.rs b/src/test/ui/chalkify/lower_env3.rs
new file mode 100644
index 00000000000..673f08d78ab
--- /dev/null
+++ b/src/test/ui/chalkify/lower_env3.rs
@@ -0,0 +1,16 @@
+// check-pass
+// compile-flags: -Z chalk
+
+#![allow(dead_code)]
+
+trait Foo {
+    fn foo(&self);
+}
+
+impl<T> Foo for T where T: Clone {
+    fn foo(&self) {
+    }
+}
+
+fn main() {
+}
diff --git a/src/test/ui/chalkify/lower_impl.rs b/src/test/ui/chalkify/lower_impl.rs
new file mode 100644
index 00000000000..f586cf08391
--- /dev/null
+++ b/src/test/ui/chalkify/lower_impl.rs
@@ -0,0 +1,17 @@
+// check-pass
+// compile-flags: -Z chalk
+
+trait Foo { }
+
+impl<T: 'static> Foo for T where T: Iterator<Item = i32> { }
+
+trait Bar {
+    type Assoc;
+}
+
+impl<T> Bar for T where T: Iterator<Item = i32> {
+    type Assoc = Vec<T>;
+}
+
+fn main() {
+}
diff --git a/src/test/ui/chalkify/lower_struct.rs b/src/test/ui/chalkify/lower_struct.rs
new file mode 100644
index 00000000000..94a0716d383
--- /dev/null
+++ b/src/test/ui/chalkify/lower_struct.rs
@@ -0,0 +1,8 @@
+// check-pass
+// compile-flags: -Z chalk
+
+struct Foo<'a, T> where Box<T>: Clone {
+    _x: std::marker::PhantomData<&'a T>,
+}
+
+fn main() { }
diff --git a/src/test/ui/chalkify/lower_trait.rs b/src/test/ui/chalkify/lower_trait.rs
new file mode 100644
index 00000000000..d8f6180ceb3
--- /dev/null
+++ b/src/test/ui/chalkify/lower_trait.rs
@@ -0,0 +1,11 @@
+// check-pass
+// compile-flags: -Z chalk
+
+trait Bar { }
+
+trait Foo<S, T: ?Sized> {
+    type Assoc: Bar + ?Sized;
+}
+
+fn main() {
+}
diff --git a/src/test/ui/chalkify/lower_trait_higher_rank.rs b/src/test/ui/chalkify/lower_trait_higher_rank.rs
new file mode 100644
index 00000000000..a48979491a1
--- /dev/null
+++ b/src/test/ui/chalkify/lower_trait_higher_rank.rs
@@ -0,0 +1,9 @@
+// check-pass
+// compile-flags: -Z chalk
+
+trait Foo<F: ?Sized> where for<'a> F: Fn(&'a (u8, u16)) -> &'a u8
+{
+}
+
+fn main() {
+}
diff --git a/src/test/ui/chalkify/lower_trait_where_clause.rs b/src/test/ui/chalkify/lower_trait_where_clause.rs
new file mode 100644
index 00000000000..19cff8db7cb
--- /dev/null
+++ b/src/test/ui/chalkify/lower_trait_where_clause.rs
@@ -0,0 +1,16 @@
+// check-pass
+// compile-flags: -Z chalk
+
+use std::borrow::Borrow;
+
+trait Foo<'a, 'b, T, U>
+where
+    T: Borrow<U> + ?Sized,
+    U: ?Sized + 'b,
+    'a: 'b,
+    Box<T>:, // NOTE(#53696) this checks an empty list of bounds.
+{
+}
+
+fn main() {
+}
diff --git a/src/test/ui/chalkify/println.rs b/src/test/ui/chalkify/println.rs
new file mode 100644
index 00000000000..cf36aef8afa
--- /dev/null
+++ b/src/test/ui/chalkify/println.rs
@@ -0,0 +1,7 @@
+// check-pass
+// compile-flags: -Z chalk
+
+fn main() {
+    // FIXME(chalk): Require `RegionOutlives`/`TypeOutlives`/`Subtype` support
+    //println!("hello");
+}
diff --git a/src/test/ui/chalkify/projection.rs b/src/test/ui/chalkify/projection.rs
new file mode 100644
index 00000000000..d6a8dd7a4a2
--- /dev/null
+++ b/src/test/ui/chalkify/projection.rs
@@ -0,0 +1,25 @@
+// run-pass
+// compile-flags: -Z chalk
+
+trait Foo { }
+
+trait Bar {
+    type Item: Foo;
+}
+
+impl Foo for i32 { }
+impl Bar for i32 {
+    type Item = i32;
+}
+
+fn only_foo<T: Foo>() { }
+
+fn only_bar<T: Bar>() {
+    // `T` implements `Bar` hence `<T as Bar>::Item` must also implement `Bar`
+    only_foo::<T::Item>()
+}
+
+fn main() {
+    only_bar::<i32>();
+    only_foo::<<i32 as Bar>::Item>();
+}
diff --git a/src/test/ui/chalkify/recursive_where_clause_on_type.rs b/src/test/ui/chalkify/recursive_where_clause_on_type.rs
new file mode 100644
index 00000000000..6ee13f5e7a1
--- /dev/null
+++ b/src/test/ui/chalkify/recursive_where_clause_on_type.rs
@@ -0,0 +1,35 @@
+// FIXME(chalk): should fail, see comments
+// check-pass
+// compile-flags: -Z chalk
+
+#![feature(trivial_bounds)]
+
+trait Bar {
+    fn foo();
+}
+trait Foo: Bar { }
+
+struct S where S: Foo;
+//~^ WARN Trait bound S: Foo does not depend on any type or lifetime parameters
+
+impl Foo for S {
+}
+
+fn bar<T: Bar>() {
+    T::foo();
+}
+
+fn foo<T: Foo>() {
+    bar::<T>()
+}
+
+fn main() {
+    // For some reason, the error is duplicated...
+
+    // FIXME(chalk): this order of this duplicate error seems non-determistic
+    // and causes test to fail
+    /*
+    foo::<S>() // ERROR the type `S` is not well-formed (chalk)
+    //^ ERROR the type `S` is not well-formed (chalk)
+    */
+}
diff --git a/src/test/ui/chalkify/recursive_where_clause_on_type.stderr b/src/test/ui/chalkify/recursive_where_clause_on_type.stderr
new file mode 100644
index 00000000000..a5b7ef7fdb2
--- /dev/null
+++ b/src/test/ui/chalkify/recursive_where_clause_on_type.stderr
@@ -0,0 +1,10 @@
+warning: Trait bound S: Foo does not depend on any type or lifetime parameters
+  --> $DIR/recursive_where_clause_on_type.rs:12:19
+   |
+LL | struct S where S: Foo;
+   |                   ^^^
+   |
+   = note: `#[warn(trivial_bounds)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/chalkify/super_trait.rs b/src/test/ui/chalkify/super_trait.rs
new file mode 100644
index 00000000000..eeff9fd9b80
--- /dev/null
+++ b/src/test/ui/chalkify/super_trait.rs
@@ -0,0 +1,19 @@
+// run-pass
+// compile-flags: -Z chalk
+
+trait Foo { }
+trait Bar: Foo { }
+
+impl Foo for i32 { }
+impl Bar for i32 { }
+
+fn only_foo<T: Foo>() { }
+
+fn only_bar<T: Bar>() {
+    // `T` implements `Bar` hence `T` must also implement `Foo`
+    only_foo::<T>()
+}
+
+fn main() {
+    only_bar::<i32>()
+}
diff --git a/src/test/ui/chalkify/trait_implied_bound.rs b/src/test/ui/chalkify/trait_implied_bound.rs
new file mode 100644
index 00000000000..8a2e1cf5990
--- /dev/null
+++ b/src/test/ui/chalkify/trait_implied_bound.rs
@@ -0,0 +1,18 @@
+// run-pass
+// compile-flags: -Z chalk
+
+trait Foo { }
+trait Bar<U> where U: Foo { }
+
+impl Foo for i32 { }
+impl Bar<i32> for i32 { }
+
+fn only_foo<T: Foo>() { }
+
+fn only_bar<U, T: Bar<U>>() {
+    only_foo::<U>()
+}
+
+fn main() {
+    only_bar::<i32, i32>()
+}
diff --git a/src/test/ui/chalkify/type_implied_bound.rs b/src/test/ui/chalkify/type_implied_bound.rs
new file mode 100644
index 00000000000..8673f5319bd
--- /dev/null
+++ b/src/test/ui/chalkify/type_implied_bound.rs
@@ -0,0 +1,29 @@
+// run-pass
+// compile-flags: -Z chalk
+
+trait Eq { }
+trait Hash: Eq { }
+
+impl Eq for i32 { }
+impl Hash for i32 { }
+
+struct Set<T: Hash> {
+    _x: T,
+}
+
+fn only_eq<T: Eq>() { }
+
+fn take_a_set<T>(_: &Set<T>) {
+    // `Set<T>` is an input type of `take_a_set`, hence we know that
+    // `T` must implement `Hash`, and we know in turn that `T` must
+    // implement `Eq`.
+    only_eq::<T>()
+}
+
+fn main() {
+    let set = Set {
+        _x: 5,
+    };
+
+    take_a_set(&set);
+}
diff --git a/src/test/ui/chalkify/type_inference.rs b/src/test/ui/chalkify/type_inference.rs
new file mode 100644
index 00000000000..5175c5d062a
--- /dev/null
+++ b/src/test/ui/chalkify/type_inference.rs
@@ -0,0 +1,28 @@
+// compile-flags: -Z chalk
+
+trait Foo { }
+impl Foo for i32 { }
+
+trait Bar { }
+impl Bar for i32 { }
+impl Bar for u32 { }
+
+fn only_foo<T: Foo>(_x: T) { }
+
+fn only_bar<T: Bar>(_x: T) { }
+
+fn main() {
+    let x = 5.0;
+
+    // The only type which implements `Foo` is `i32`, so the chalk trait solver
+    // is expecting a variable of type `i32`. This behavior differs from the
+    // old-style trait solver. I guess this will change, that's why I'm
+    // adding that test.
+    // FIXME(chalk): partially blocked on float/int special casing
+    only_foo(x); //~ ERROR the trait bound `f64: Foo` is not satisfied
+
+    // Here we have two solutions so we get back the behavior of the old-style
+    // trait solver.
+    // FIXME(chalk): blocked on float/int special casing
+    //only_bar(x); // ERROR the trait bound `{float}: Bar` is not satisfied
+}
diff --git a/src/test/ui/chalkify/type_inference.stderr b/src/test/ui/chalkify/type_inference.stderr
new file mode 100644
index 00000000000..ee9e67c6c78
--- /dev/null
+++ b/src/test/ui/chalkify/type_inference.stderr
@@ -0,0 +1,12 @@
+error[E0277]: the trait bound `f64: Foo` is not satisfied
+  --> $DIR/type_inference.rs:22:5
+   |
+LL | fn only_foo<T: Foo>(_x: T) { }
+   |                --- required by this bound in `only_foo`
+...
+LL |     only_foo(x);
+   |     ^^^^^^^^ the trait `Foo` is not implemented for `f64`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/chalkify/type_wf.rs b/src/test/ui/chalkify/type_wf.rs
new file mode 100644
index 00000000000..396baf814a0
--- /dev/null
+++ b/src/test/ui/chalkify/type_wf.rs
@@ -0,0 +1,32 @@
+// FIXME(chalk): should have an error, see below
+// check-pass
+// compile-flags: -Z chalk
+
+trait Foo { }
+
+struct S<T: Foo> {
+    x: T,
+}
+
+impl Foo for i32 { }
+impl<T> Foo for Option<T> { }
+
+fn main() {
+    let s = S {
+       x: 5,
+    };
+
+    // FIXME(chalk): blocked on float/int special handling. Needs to know that {float}: !i32
+    /*
+    let s = S { // ERROR the trait bound `{float}: Foo` is not satisfied
+        x: 5.0,
+    };
+    */
+
+    // FIXME(chalk): blocked on float/int special handling. Needs to know that {float}: Sized
+    /*
+    let s = S {
+        x: Some(5.0),
+    };
+    */
+}
diff --git a/src/test/run-fail/diverging-closure.rs b/src/test/ui/closures/diverging-closure.rs
index a92e07a21fe..1213a883ef0 100644
--- a/src/test/run-fail/diverging-closure.rs
+++ b/src/test/ui/closures/diverging-closure.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:oops
+// ignore-emscripten no processes
 
 fn main() {
     let func = || -> ! {
diff --git a/src/test/run-fail/promoted_div_by_zero.rs b/src/test/ui/consts/promoted_div_by_zero.rs
index dc6719ce025..b4503f691ff 100644
--- a/src/test/run-fail/promoted_div_by_zero.rs
+++ b/src/test/ui/consts/promoted_div_by_zero.rs
@@ -1,6 +1,8 @@
 #![allow(unconditional_panic, const_err)]
 
+// run-fail
 // error-pattern: attempt to divide by zero
+// ignore-emscripten no processes
 
 fn main() {
     let x = &(1 / (1 - 1));
diff --git a/src/test/run-fail/expr-fn-panic.rs b/src/test/ui/fn/expr-fn-panic.rs
index 0532c32ec70..123b57f97a4 100644
--- a/src/test/run-fail/expr-fn-panic.rs
+++ b/src/test/ui/fn/expr-fn-panic.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:explicit panic
+// ignore-emscripten no processes
 
 fn f() -> ! {
     panic!()
diff --git a/src/test/run-fail/generator-resume-after-panic.rs b/src/test/ui/generator/generator-resume-after-panic.rs
index 1a7c2e80629..55704f40e9f 100644
--- a/src/test/run-fail/generator-resume-after-panic.rs
+++ b/src/test/ui/generator/generator-resume-after-panic.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:generator resumed after panicking
+// ignore-emscripten no processes
 
 // Test that we get the correct message for resuming a panicked generator.
 
diff --git a/src/test/run-fail/hashmap-capacity-overflow.rs b/src/test/ui/hashmap/hashmap-capacity-overflow.rs
index 038f2756ff3..5f88683f4ad 100644
--- a/src/test/run-fail/hashmap-capacity-overflow.rs
+++ b/src/test/ui/hashmap/hashmap-capacity-overflow.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:capacity overflow
+// ignore-emscripten no processes
 
 use std::collections::hash_map::HashMap;
 use std::usize;
diff --git a/src/test/ui/hashmap-iter-value-lifetime.nll.stderr b/src/test/ui/hashmap/hashmap-iter-value-lifetime.nll.stderr
index 312a91adca6..312a91adca6 100644
--- a/src/test/ui/hashmap-iter-value-lifetime.nll.stderr
+++ b/src/test/ui/hashmap/hashmap-iter-value-lifetime.nll.stderr
diff --git a/src/test/ui/hashmap-iter-value-lifetime.rs b/src/test/ui/hashmap/hashmap-iter-value-lifetime.rs
index 260ea8c7ae1..260ea8c7ae1 100644
--- a/src/test/ui/hashmap-iter-value-lifetime.rs
+++ b/src/test/ui/hashmap/hashmap-iter-value-lifetime.rs
diff --git a/src/test/ui/hashmap-iter-value-lifetime.stderr b/src/test/ui/hashmap/hashmap-iter-value-lifetime.stderr
index f7626b13bad..f7626b13bad 100644
--- a/src/test/ui/hashmap-iter-value-lifetime.stderr
+++ b/src/test/ui/hashmap/hashmap-iter-value-lifetime.stderr
diff --git a/src/test/ui/hashmap-lifetimes.nll.stderr b/src/test/ui/hashmap/hashmap-lifetimes.nll.stderr
index aa8e890c168..aa8e890c168 100644
--- a/src/test/ui/hashmap-lifetimes.nll.stderr
+++ b/src/test/ui/hashmap/hashmap-lifetimes.nll.stderr
diff --git a/src/test/ui/hashmap-lifetimes.rs b/src/test/ui/hashmap/hashmap-lifetimes.rs
index 295bf3b0e66..295bf3b0e66 100644
--- a/src/test/ui/hashmap-lifetimes.rs
+++ b/src/test/ui/hashmap/hashmap-lifetimes.rs
diff --git a/src/test/ui/hashmap-lifetimes.stderr b/src/test/ui/hashmap/hashmap-lifetimes.stderr
index 497c7d1216c..497c7d1216c 100644
--- a/src/test/ui/hashmap-lifetimes.stderr
+++ b/src/test/ui/hashmap/hashmap-lifetimes.stderr
diff --git a/src/test/ui/hashmap-memory.rs b/src/test/ui/hashmap/hashmap-memory.rs
index 3129eb0da82..3129eb0da82 100644
--- a/src/test/ui/hashmap-memory.rs
+++ b/src/test/ui/hashmap/hashmap-memory.rs
diff --git a/src/test/run-fail/expr-if-panic-fn.rs b/src/test/ui/if/expr-if-panic-fn.rs
index 660b1396e38..36e49785a49 100644
--- a/src/test/run-fail/expr-if-panic-fn.rs
+++ b/src/test/ui/if/expr-if-panic-fn.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:explicit panic
+// ignore-emscripten no processes
 
 fn f() -> ! {
     panic!()
diff --git a/src/test/run-fail/expr-if-panic.rs b/src/test/ui/if/expr-if-panic.rs
index 36aaf459a56..520ee0870ee 100644
--- a/src/test/run-fail/expr-if-panic.rs
+++ b/src/test/ui/if/expr-if-panic.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:explicit panic
+// ignore-emscripten no processes
 
 fn main() {
     let _x = if false {
diff --git a/src/test/run-fail/if-check-panic.rs b/src/test/ui/if/if-check-panic.rs
index f9a4b8fcb38..037cd427ccf 100644
--- a/src/test/run-fail/if-check-panic.rs
+++ b/src/test/ui/if/if-check-panic.rs
@@ -1,4 +1,7 @@
+// run-fail
 // error-pattern:Number is odd
+// ignore-emscripten no processes
+
 fn even(x: usize) -> bool {
     if x < 2 {
         return false;
diff --git a/src/test/run-fail/if-cond-bot.rs b/src/test/ui/if/if-cond-bot.rs
index c680cad258f..bcd11467852 100644
--- a/src/test/run-fail/if-cond-bot.rs
+++ b/src/test/ui/if/if-cond-bot.rs
@@ -1,8 +1,12 @@
+// run-fail
 // error-pattern:quux
+// ignore-emscripten no processes
+
 fn my_err(s: String) -> ! {
     println!("{}", s);
     panic!("quux");
 }
+
 fn main() {
     if my_err("bye".to_string()) {
     }
diff --git a/src/test/run-fail/glob-use-std.rs b/src/test/ui/imports/glob-use-std.rs
index d19a782986b..ef06cc570d5 100644
--- a/src/test/run-fail/glob-use-std.rs
+++ b/src/test/ui/imports/glob-use-std.rs
@@ -1,6 +1,8 @@
 // Issue #7580
 
+// run-fail
 // error-pattern:panic works
+// ignore-emscripten no processes
 
 use std::*;
 
diff --git a/src/test/run-fail/issue-12920.rs b/src/test/ui/issues/issue-12920.rs
index 0819e992d13..a0cfea055be 100644
--- a/src/test/run-fail/issue-12920.rs
+++ b/src/test/ui/issues/issue-12920.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:explicit panic
+// ignore-emscripten no processes
 
 pub fn main() {
     panic!();
diff --git a/src/test/run-fail/issue-13202.rs b/src/test/ui/issues/issue-13202.rs
index cf3a6b3d986..16debb5b6c4 100644
--- a/src/test/run-fail/issue-13202.rs
+++ b/src/test/ui/issues/issue-13202.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:bad input
+// ignore-emscripten no processes
 
 fn main() {
     Some("foo").unwrap_or(panic!("bad input")).to_string();
diff --git a/src/test/run-fail/issue-18576.rs b/src/test/ui/issues/issue-18576.rs
index ca9d1e5f5e7..389cf108b05 100644
--- a/src/test/run-fail/issue-18576.rs
+++ b/src/test/ui/issues/issue-18576.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:stop
+// ignore-emscripten no processes
 
 // #18576
 // Make sure that calling an extern function pointer in an unreachable
@@ -10,4 +12,5 @@ fn main() {
     let pointer = other;
     pointer();
 }
+
 extern "C" fn other() {}
diff --git a/src/test/run-fail/issue-20971.rs b/src/test/ui/issues/issue-20971.rs
index 6c2de783c01..2e10418178c 100644
--- a/src/test/run-fail/issue-20971.rs
+++ b/src/test/ui/issues/issue-20971.rs
@@ -1,6 +1,8 @@
 // Regression test for Issue #20971.
 
+// run-fail
 // error-pattern:Hello, world!
+// ignore-emscripten no processes
 
 pub trait Parser {
     type Input;
@@ -12,7 +14,7 @@ impl Parser for () {
     fn parse(&mut self, input: ()) {}
 }
 
-pub fn many() -> Box<Parser<Input = <() as Parser>::Input> + 'static> {
+pub fn many() -> Box<dyn Parser<Input = <() as Parser>::Input> + 'static> {
     panic!("Hello, world!")
 }
 
diff --git a/src/test/run-fail/issue-23354-2.rs b/src/test/ui/issues/issue-23354-2.rs
index 8f7baff56dc..c291d8a5eaf 100644
--- a/src/test/run-fail/issue-23354-2.rs
+++ b/src/test/ui/issues/issue-23354-2.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:panic evaluated
+// ignore-emscripten no processes
 
 #[allow(unused_variables)]
 fn main() {
diff --git a/src/test/run-fail/issue-23354.rs b/src/test/ui/issues/issue-23354.rs
index 4c2fb022a6b..8b7c2eef2fc 100644
--- a/src/test/run-fail/issue-23354.rs
+++ b/src/test/ui/issues/issue-23354.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:panic evaluated
+// ignore-emscripten no processes
 
 #[allow(unused_variables)]
 fn main() {
diff --git a/src/test/run-fail/issue-2444.rs b/src/test/ui/issues/issue-2444.rs
index 17f89e4d20d..ac0d0506a34 100644
--- a/src/test/run-fail/issue-2444.rs
+++ b/src/test/ui/issues/issue-2444.rs
@@ -1,12 +1,14 @@
+// run-fail
 // error-pattern:explicit panic
+// ignore-emscripten no processes
 
 use std::sync::Arc;
 
-enum e<T> {
-    ee(Arc<T>),
+enum Err<T> {
+    Errr(Arc<T>),
 }
 
-fn foo() -> e<isize> {
+fn foo() -> Err<isize> {
     panic!();
 }
 
diff --git a/src/test/run-fail/bug-2470-bounds-check-overflow.rs b/src/test/ui/issues/issue-2470-bounds-check-overflow.rs
index b4e3f246991..f0e8e185e56 100644
--- a/src/test/run-fail/bug-2470-bounds-check-overflow.rs
+++ b/src/test/ui/issues/issue-2470-bounds-check-overflow.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:index out of bounds
+// ignore-emscripten no processes
 
 use std::mem;
 
diff --git a/src/test/run-fail/issue-2761.rs b/src/test/ui/issues/issue-2761.rs
index 84d90930d2d..3ba098abbe6 100644
--- a/src/test/run-fail/issue-2761.rs
+++ b/src/test/ui/issues/issue-2761.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:custom message
+// ignore-emscripten no processes
 
 fn main() {
     assert!(false, "custom message");
diff --git a/src/test/run-fail/issue-28934.rs b/src/test/ui/issues/issue-28934.rs
index 5915372b692..1e48878f632 100644
--- a/src/test/run-fail/issue-28934.rs
+++ b/src/test/ui/issues/issue-28934.rs
@@ -1,7 +1,9 @@
 // Regression test: issue had to do with "givens" in region inference,
 // which were not being considered during the contraction phase.
 
+// run-fail
 // error-pattern:explicit panic
+// ignore-emscripten no processes
 
 struct Parser<'i: 't, 't>(&'i u8, &'t u8);
 
diff --git a/src/test/run-fail/issue-29798.rs b/src/test/ui/issues/issue-29798.rs
index b06aa5fc728..5eff5d1915b 100644
--- a/src/test/run-fail/issue-29798.rs
+++ b/src/test/ui/issues/issue-29798.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:index out of bounds: the len is 5 but the index is 5
+// ignore-emscripten no processes
 
 const fn test(x: usize) -> i32 {
     [42;5][x]
diff --git a/src/test/run-fail/issue-3029.rs b/src/test/ui/issues/issue-3029.rs
index face808b68f..a5d30960a4c 100644
--- a/src/test/run-fail/issue-3029.rs
+++ b/src/test/ui/issues/issue-3029.rs
@@ -1,9 +1,11 @@
+// run-fail
+// error-pattern:so long
+// ignore-emscripten no processes
+
 #![allow(unused_allocation)]
 #![allow(unreachable_code)]
 #![allow(unused_variables)]
 
-
-// error-pattern:so long
 fn main() {
     let mut x = Vec::new();
     let y = vec![3];
diff --git a/src/test/run-fail/issue-30380.rs b/src/test/ui/issues/issue-30380.rs
index 036071a89c7..48b329c5de1 100644
--- a/src/test/run-fail/issue-30380.rs
+++ b/src/test/ui/issues/issue-30380.rs
@@ -1,7 +1,9 @@
 // check that panics in destructors during assignment do not leave
 // destroyed values lying around for other destructors to observe.
 
+// run-fail
 // error-pattern:panicking destructors ftw!
+// ignore-emscripten no processes
 
 struct Observer<'a>(&'a mut FilledOnDrop);
 
diff --git a/src/test/run-fail/issue-44216-add-instant.rs b/src/test/ui/issues/issue-44216-add-instant.rs
index 76ad0a3d41b..c2f3598f645 100644
--- a/src/test/run-fail/issue-44216-add-instant.rs
+++ b/src/test/ui/issues/issue-44216-add-instant.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:overflow
+// ignore-emscripten no processes
 
 use std::time::{Instant, Duration};
 
diff --git a/src/test/run-fail/issue-44216-add-system-time.rs b/src/test/ui/issues/issue-44216-add-system-time.rs
index aa861f7d599..9a88cb7c189 100644
--- a/src/test/run-fail/issue-44216-add-system-time.rs
+++ b/src/test/ui/issues/issue-44216-add-system-time.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:overflow
+// ignore-emscripten no processes
 
 use std::time::{Duration, SystemTime};
 
diff --git a/src/test/run-fail/issue-44216-sub-instant.rs b/src/test/ui/issues/issue-44216-sub-instant.rs
index 8bc1f47ae2d..2decd88bbc0 100644
--- a/src/test/run-fail/issue-44216-sub-instant.rs
+++ b/src/test/ui/issues/issue-44216-sub-instant.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:overflow
+// ignore-emscripten no processes
 
 use std::time::{Instant, Duration};
 
diff --git a/src/test/run-fail/issue-44216-sub-system-time.rs b/src/test/ui/issues/issue-44216-sub-system-time.rs
index 37ab0e7c3f9..e58a31a41a5 100644
--- a/src/test/run-fail/issue-44216-sub-system-time.rs
+++ b/src/test/ui/issues/issue-44216-sub-system-time.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:overflow
+// ignore-emscripten no processes
 
 use std::time::{Duration, SystemTime};
 
diff --git a/src/test/run-fail/issue-51345.rs b/src/test/ui/issues/issue-51345-2.rs
index c62f98ea78d..52f342a8500 100644
--- a/src/test/run-fail/issue-51345.rs
+++ b/src/test/ui/issues/issue-51345-2.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern: thread 'main' panicked at 'explicit panic'
+// ignore-emscripten no processes
 
 fn main() {
     let mut vec = vec![];
diff --git a/src/test/run-fail/issue-6458-1.rs b/src/test/ui/issues/issue-6458-1.rs
index 550bb2b832f..184e4832b90 100644
--- a/src/test/run-fail/issue-6458-1.rs
+++ b/src/test/ui/issues/issue-6458-1.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:explicit panic
+// ignore-emscripten no processes
 
 fn foo<T>(t: T) {}
 fn main() {
diff --git a/src/test/ui/issues/issue-811.rs b/src/test/ui/issues/issue-811.rs
new file mode 100644
index 00000000000..f929d388819
--- /dev/null
+++ b/src/test/ui/issues/issue-811.rs
@@ -0,0 +1,26 @@
+// run-fail
+// error-pattern:quux
+// ignore-emscripten no processes
+
+use std::marker::PhantomData;
+
+fn test00_start(ch: Chan<isize>, message: isize) {
+    send(ch, message);
+}
+
+type TaskId = isize;
+type PortId = isize;
+
+struct Chan<T> {
+    task: TaskId,
+    port: PortId,
+    marker: PhantomData<*mut T>,
+}
+
+fn send<T: Send>(_ch: Chan<T>, _data: T) {
+    panic!();
+}
+
+fn main() {
+    panic!("quux");
+}
diff --git a/src/test/run-fail/issue-948.rs b/src/test/ui/issues/issue-948.rs
index 8f1c6587f03..b9bbeb3951e 100644
--- a/src/test/run-fail/issue-948.rs
+++ b/src/test/ui/issues/issue-948.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:beep boop
+// ignore-emscripten no processes
 
 #![allow(unused_variables)]
 
diff --git a/src/test/run-fail/for-each-loop-panic.rs b/src/test/ui/loops/for-each-loop-panic.rs
index d24e81e152c..5156999f4db 100644
--- a/src/test/run-fail/for-each-loop-panic.rs
+++ b/src/test/ui/loops/for-each-loop-panic.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:moop
+// ignore-emscripten no processes
 
 fn main() {
     for _ in 0_usize..10_usize {
diff --git a/src/test/run-fail/assert-as-macro.rs b/src/test/ui/macros/assert-as-macro.rs
index f715e21f781..23c05480813 100644
--- a/src/test/run-fail/assert-as-macro.rs
+++ b/src/test/ui/macros/assert-as-macro.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:assertion failed: 1 == 2
+// ignore-emscripten no processes
 
 fn main() {
     assert!(1 == 2);
diff --git a/src/test/run-fail/assert-eq-macro-panic.rs b/src/test/ui/macros/assert-eq-macro-panic.rs
index 863fec12d74..5e505c30b35 100644
--- a/src/test/run-fail/assert-eq-macro-panic.rs
+++ b/src/test/ui/macros/assert-eq-macro-panic.rs
@@ -1,6 +1,8 @@
+// run-fail
 // error-pattern:assertion failed: `(left == right)`
 // error-pattern: left: `14`
 // error-pattern:right: `15`
+// ignore-emscripten no processes
 
 fn main() {
     assert_eq!(14, 15);
diff --git a/src/test/run-fail/assert-macro-explicit.rs b/src/test/ui/macros/assert-macro-explicit.rs
index 3689323c999..578ef563278 100644
--- a/src/test/run-fail/assert-macro-explicit.rs
+++ b/src/test/ui/macros/assert-macro-explicit.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:panicked at 'assertion failed: false'
+// ignore-emscripten no processes
 
 fn main() {
     assert!(false);
diff --git a/src/test/run-fail/assert-macro-fmt.rs b/src/test/ui/macros/assert-macro-fmt.rs
index 9fbfb085c2f..b8d319d85f4 100644
--- a/src/test/run-fail/assert-macro-fmt.rs
+++ b/src/test/ui/macros/assert-macro-fmt.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:panicked at 'test-assert-fmt 42 rust'
+// ignore-emscripten no processes
 
 fn main() {
     assert!(false, "test-assert-fmt {} {}", 42, "rust");
diff --git a/src/test/run-fail/assert-macro-owned.rs b/src/test/ui/macros/assert-macro-owned.rs
index bd58d35eb71..b50fe65c015 100644
--- a/src/test/run-fail/assert-macro-owned.rs
+++ b/src/test/ui/macros/assert-macro-owned.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:panicked at 'test-assert-owned'
+// ignore-emscripten no processes
 
 fn main() {
     assert!(false, "test-assert-owned".to_string());
diff --git a/src/test/run-fail/assert-macro-static.rs b/src/test/ui/macros/assert-macro-static.rs
index 650aaeab4f6..dc5274a7e88 100644
--- a/src/test/run-fail/assert-macro-static.rs
+++ b/src/test/ui/macros/assert-macro-static.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:panicked at 'test-assert-static'
+// ignore-emscripten no processes
 
 fn main() {
     assert!(false, "test-assert-static");
diff --git a/src/test/run-fail/assert-ne-macro-panic.rs b/src/test/ui/macros/assert-ne-macro-panic.rs
index f55ef2b3ff5..4f507d7b54d 100644
--- a/src/test/run-fail/assert-ne-macro-panic.rs
+++ b/src/test/ui/macros/assert-ne-macro-panic.rs
@@ -1,6 +1,8 @@
+// run-fail
 // error-pattern:assertion failed: `(left != right)`
 // error-pattern: left: `14`
 // error-pattern:right: `14`
+// ignore-emscripten no processes
 
 fn main() {
     assert_ne!(14, 14);
diff --git a/src/test/run-fail/die-macro.rs b/src/test/ui/macros/die-macro-2.rs
index 846b9ea24d3..ebbce528a18 100644
--- a/src/test/run-fail/die-macro.rs
+++ b/src/test/ui/macros/die-macro-2.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:test
+// ignore-emscripten no processes
 
 fn main() {
     panic!("test");
diff --git a/src/test/run-fail/die-macro-expr.rs b/src/test/ui/macros/die-macro-expr.rs
index 70413f97896..c4b5f68ddf9 100644
--- a/src/test/run-fail/die-macro-expr.rs
+++ b/src/test/ui/macros/die-macro-expr.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:test
+// ignore-emscripten no processes
 
 fn main() {
     let __isize: isize = panic!("test");
diff --git a/src/test/run-fail/die-macro-pure.rs b/src/test/ui/macros/die-macro-pure.rs
index cec0742d503..588fbe61b0e 100644
--- a/src/test/run-fail/die-macro-pure.rs
+++ b/src/test/ui/macros/die-macro-pure.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:test
+// ignore-emscripten no processes
 
 fn f() {
     panic!("test");
diff --git a/src/test/run-fail/unimplemented-macro-panic.rs b/src/test/ui/macros/unimplemented-macro-panic.rs
index 4d9cb740fc6..e7169903f8e 100644
--- a/src/test/run-fail/unimplemented-macro-panic.rs
+++ b/src/test/ui/macros/unimplemented-macro-panic.rs
@@ -1,4 +1,7 @@
+// run-fail
 // error-pattern:not implemented
+// ignore-emscripten no processes
+
 fn main() {
     unimplemented!()
 }
diff --git a/src/test/run-fail/unreachable-fmt-msg.rs b/src/test/ui/macros/unreachable-fmt-msg.rs
index ac2a52163b4..eb17ed92711 100644
--- a/src/test/run-fail/unreachable-fmt-msg.rs
+++ b/src/test/ui/macros/unreachable-fmt-msg.rs
@@ -1,4 +1,7 @@
+// run-fail
 // error-pattern:internal error: entered unreachable code: 6 is not prime
+// ignore-emscripten no processes
+
 fn main() {
     unreachable!("{} is not {}", 6u32, "prime");
 }
diff --git a/src/test/run-fail/unreachable-macro-panic.rs b/src/test/ui/macros/unreachable-macro-panic.rs
index 597a0144722..55e2102e2cc 100644
--- a/src/test/run-fail/unreachable-macro-panic.rs
+++ b/src/test/ui/macros/unreachable-macro-panic.rs
@@ -1,4 +1,7 @@
+// run-fail
 // error-pattern:internal error: entered unreachable code
+// ignore-emscripten no processes
+
 fn main() {
     unreachable!()
 }
diff --git a/src/test/run-fail/unreachable-static-msg.rs b/src/test/ui/macros/unreachable-static-msg.rs
index 40a2881cc57..55edf3af7d9 100644
--- a/src/test/run-fail/unreachable-static-msg.rs
+++ b/src/test/ui/macros/unreachable-static-msg.rs
@@ -1,4 +1,7 @@
+// run-fail
 // error-pattern:internal error: entered unreachable code: uhoh
+// ignore-emscripten no processes
+
 fn main() {
     unreachable!("uhoh")
 }
diff --git a/src/test/run-fail/unreachable.rs b/src/test/ui/macros/unreachable.rs
index 597a0144722..55e2102e2cc 100644
--- a/src/test/run-fail/unreachable.rs
+++ b/src/test/ui/macros/unreachable.rs
@@ -1,4 +1,7 @@
+// run-fail
 // error-pattern:internal error: entered unreachable code
+// ignore-emscripten no processes
+
 fn main() {
     unreachable!()
 }
diff --git a/src/test/run-fail/expr-match-panic-fn.rs b/src/test/ui/match/expr-match-panic-fn.rs
index 120df61b4bf..ea471717e88 100644
--- a/src/test/run-fail/expr-match-panic-fn.rs
+++ b/src/test/ui/match/expr-match-panic-fn.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:explicit panic
+// ignore-emscripten no processes
 
 fn f() -> ! {
     panic!()
diff --git a/src/test/run-fail/expr-match-panic.rs b/src/test/ui/match/expr-match-panic.rs
index b2f0179a083..53f8a8bd30d 100644
--- a/src/test/run-fail/expr-match-panic.rs
+++ b/src/test/ui/match/expr-match-panic.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:explicit panic
+// ignore-emscripten no processes
 
 fn main() {
     let _x = match true {
diff --git a/src/test/run-fail/match-bot-panic.rs b/src/test/ui/match/match-bot-panic.rs
index f4da8c4e43f..e4a6f6d6fe4 100644
--- a/src/test/run-fail/match-bot-panic.rs
+++ b/src/test/ui/match/match-bot-panic.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:explicit panic
+// ignore-emscripten no processes
 
 #![allow(unreachable_code)]
 #![allow(unused_variables)]
diff --git a/src/test/run-fail/match-disc-bot.rs b/src/test/ui/match/match-disc-bot.rs
index a9312fbb1fb..18cfd5e2395 100644
--- a/src/test/run-fail/match-disc-bot.rs
+++ b/src/test/ui/match/match-disc-bot.rs
@@ -1,4 +1,7 @@
+// run-fail
 // error-pattern:quux
+// ignore-emscripten no processes
+
 fn f() -> ! {
     panic!("quux")
 }
diff --git a/src/test/run-fail/match-wildcards.rs b/src/test/ui/match/match-wildcards.rs
index 7a65ad52558..43f6e4913ac 100644
--- a/src/test/run-fail/match-wildcards.rs
+++ b/src/test/ui/match/match-wildcards.rs
@@ -1,4 +1,7 @@
+// run-fail
 // error-pattern:squirrelcupcake
+// ignore-emscripten no processes
+
 fn cmp() -> isize {
     match (Some('a'), None::<char>) {
         (Some(_), _) => {
diff --git a/src/test/run-fail/meta-revision-bad.rs b/src/test/ui/meta-revision-bad.rs
index 17f6398b735..01f1518c1c6 100644
--- a/src/test/run-fail/meta-revision-bad.rs
+++ b/src/test/ui/meta-revision-bad.rs
@@ -1,6 +1,7 @@
 // Meta test for compiletest: check that when we give the wrong error
 // patterns, the test fails.
 
+// run-fail
 // revisions: foo bar
 // should-fail
 //[foo] error-pattern:bar
diff --git a/src/test/run-fail/meta-revision-ok.rs b/src/test/ui/meta-revision-ok.rs
index 8693ee5f4ef..7df9a6ea48f 100644
--- a/src/test/run-fail/meta-revision-ok.rs
+++ b/src/test/ui/meta-revision-ok.rs
@@ -1,9 +1,11 @@
 // Meta test for compiletest: check that when we give the right error
 // patterns, the test passes. See all `meta-revision-bad.rs`.
 
+// run-fail
 // revisions: foo bar
 //[foo] error-pattern:foo
 //[bar] error-pattern:bar
+// ignore-emscripten no processes
 
 #[cfg(foo)]
 fn die() {
diff --git a/src/test/run-fail/mir_codegen_calls_converging_drops.rs b/src/test/ui/mir/mir_codegen_calls_converging_drops.rs
index ee0dc98ce68..b562f930814 100644
--- a/src/test/run-fail/mir_codegen_calls_converging_drops.rs
+++ b/src/test/ui/mir/mir_codegen_calls_converging_drops.rs
@@ -1,6 +1,8 @@
+// run-fail
 // error-pattern:converging_fn called
 // error-pattern:0 dropped
 // error-pattern:exit
+// ignore-emscripten no processes
 
 struct Droppable(u8);
 impl Drop for Droppable {
diff --git a/src/test/run-fail/mir_codegen_calls_converging_drops_2.rs b/src/test/ui/mir/mir_codegen_calls_converging_drops_2.rs
index ee2c25ce856..e9446da9e39 100644
--- a/src/test/run-fail/mir_codegen_calls_converging_drops_2.rs
+++ b/src/test/ui/mir/mir_codegen_calls_converging_drops_2.rs
@@ -1,6 +1,8 @@
+// run-fail
 // error-pattern:complex called
 // error-pattern:dropped
 // error-pattern:exit
+// ignore-emscripten no processes
 
 struct Droppable;
 impl Drop for Droppable {
diff --git a/src/test/run-fail/mir_codegen_calls_diverging.rs b/src/test/ui/mir/mir_codegen_calls_diverging.rs
index dceae0a4e4a..736d580e2da 100644
--- a/src/test/run-fail/mir_codegen_calls_diverging.rs
+++ b/src/test/ui/mir/mir_codegen_calls_diverging.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:diverging_fn called
+// ignore-emscripten no processes
 
 fn diverging_fn() -> ! {
     panic!("diverging_fn called")
diff --git a/src/test/run-fail/mir_codegen_calls_diverging_drops.rs b/src/test/ui/mir/mir_codegen_calls_diverging_drops.rs
index 187e526f7c0..796d7447793 100644
--- a/src/test/run-fail/mir_codegen_calls_diverging_drops.rs
+++ b/src/test/ui/mir/mir_codegen_calls_diverging_drops.rs
@@ -1,5 +1,7 @@
+// run-fail
 // error-pattern:diverging_fn called
 // error-pattern:0 dropped
+// ignore-emscripten no processes
 
 struct Droppable(u8);
 impl Drop for Droppable {
diff --git a/src/test/run-fail/mir_drop_panics.rs b/src/test/ui/mir/mir_drop_panics.rs
index bda555b9262..bf269ee901b 100644
--- a/src/test/run-fail/mir_drop_panics.rs
+++ b/src/test/ui/mir/mir_drop_panics.rs
@@ -1,5 +1,7 @@
+// run-fail
 // error-pattern:panic 1
 // error-pattern:drop 2
+// ignore-emscripten no processes
 
 struct Droppable(u32);
 impl Drop for Droppable {
diff --git a/src/test/run-fail/mir_dynamic_drops_1.rs b/src/test/ui/mir/mir_dynamic_drops_1.rs
index db8d0af29db..a77b2368d3b 100644
--- a/src/test/run-fail/mir_dynamic_drops_1.rs
+++ b/src/test/ui/mir/mir_dynamic_drops_1.rs
@@ -1,6 +1,8 @@
+// run-fail
 // error-pattern:drop 1
 // error-pattern:drop 2
 // ignore-cloudabi no std::process
+// ignore-emscripten no processes
 
 /// Structure which will not allow to be dropped twice.
 struct Droppable<'a>(&'a mut bool, u32);
diff --git a/src/test/run-fail/mir_dynamic_drops_2.rs b/src/test/ui/mir/mir_dynamic_drops_2.rs
index 21d3a042b1e..088a16d3387 100644
--- a/src/test/run-fail/mir_dynamic_drops_2.rs
+++ b/src/test/ui/mir/mir_dynamic_drops_2.rs
@@ -1,5 +1,7 @@
+// run-fail
 // error-pattern:drop 1
 // ignore-cloudabi no std::process
+// ignore-emscripten no processes
 
 /// Structure which will not allow to be dropped twice.
 struct Droppable<'a>(&'a mut bool, u32);
diff --git a/src/test/run-fail/mir_dynamic_drops_3.rs b/src/test/ui/mir/mir_dynamic_drops_3.rs
index b9049968682..029bdcd9a15 100644
--- a/src/test/run-fail/mir_dynamic_drops_3.rs
+++ b/src/test/ui/mir/mir_dynamic_drops_3.rs
@@ -1,8 +1,10 @@
+// run-fail
 // error-pattern:unwind happens
 // error-pattern:drop 3
 // error-pattern:drop 2
 // error-pattern:drop 1
 // ignore-cloudabi no std::process
+// ignore-emscripten no processes
 
 /// Structure which will not allow to be dropped twice.
 struct Droppable<'a>(&'a mut bool, u32);
diff --git a/src/test/run-fail/mir_indexing_oob_1.rs b/src/test/ui/mir/mir_indexing_oob_1.rs
index 1cd53e309eb..6d769b6b23a 100644
--- a/src/test/run-fail/mir_indexing_oob_1.rs
+++ b/src/test/ui/mir/mir_indexing_oob_1.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:index out of bounds: the len is 5 but the index is 10
+// ignore-emscripten no processes
 
 const C: [u32; 5] = [0; 5];
 
diff --git a/src/test/run-fail/mir_indexing_oob_2.rs b/src/test/ui/mir/mir_indexing_oob_2.rs
index 64b260993c9..a9e85057015 100644
--- a/src/test/run-fail/mir_indexing_oob_2.rs
+++ b/src/test/ui/mir/mir_indexing_oob_2.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:index out of bounds: the len is 5 but the index is 10
+// ignore-emscripten no processes
 
 const C: &'static [u8; 5] = b"hello";
 
diff --git a/src/test/run-fail/mir_indexing_oob_3.rs b/src/test/ui/mir/mir_indexing_oob_3.rs
index 3688088439b..4f5cab59bfc 100644
--- a/src/test/run-fail/mir_indexing_oob_3.rs
+++ b/src/test/ui/mir/mir_indexing_oob_3.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:index out of bounds: the len is 5 but the index is 10
+// ignore-emscripten no processes
 
 const C: &'static [u8; 5] = b"hello";
 
diff --git a/src/test/run-fail/return-never-coerce.rs b/src/test/ui/never_type/return-never-coerce.rs
index 18182ff0f9d..d615940eff1 100644
--- a/src/test/run-fail/return-never-coerce.rs
+++ b/src/test/ui/never_type/return-never-coerce.rs
@@ -1,6 +1,8 @@
 // Test that ! coerces to other types.
 
+// run-fail
 // error-pattern:aah!
+// ignore-emscripten no processes
 
 fn call_another_fn<T, F: FnOnce() -> T>(f: F) -> T {
     f()
diff --git a/src/test/run-fail/divide-by-zero.rs b/src/test/ui/numbers-arithmetic/divide-by-zero.rs
index ba93563154a..30e0e6c1bdd 100644
--- a/src/test/run-fail/divide-by-zero.rs
+++ b/src/test/ui/numbers-arithmetic/divide-by-zero.rs
@@ -1,4 +1,7 @@
+// run-fail
 // error-pattern:attempt to divide by zero
+// ignore-emscripten no processes
+
 #[allow(unconditional_panic)]
 fn main() {
     let y = 0;
diff --git a/src/test/run-fail/mod-zero.rs b/src/test/ui/numbers-arithmetic/mod-zero.rs
index f70b3ac920c..08371639412 100644
--- a/src/test/run-fail/mod-zero.rs
+++ b/src/test/ui/numbers-arithmetic/mod-zero.rs
@@ -1,4 +1,7 @@
+// run-fail
 // error-pattern:attempt to calculate the remainder with a divisor of zero
+// ignore-emscripten no processes
+
 #[allow(unconditional_panic)]
 fn main() {
     let y = 0;
diff --git a/src/test/run-fail/overflowing-add.rs b/src/test/ui/numbers-arithmetic/overflowing-add.rs
index 5ca91314d95..b0f22a74b4a 100644
--- a/src/test/run-fail/overflowing-add.rs
+++ b/src/test/ui/numbers-arithmetic/overflowing-add.rs
@@ -1,5 +1,7 @@
+// run-fail
 // error-pattern:thread 'main' panicked at 'attempt to add with overflow'
 // compile-flags: -C debug-assertions
+// ignore-emscripten no processes
 
 #![allow(arithmetic_overflow)]
 
diff --git a/src/test/ui/numbers-arithmetic/overflowing-lsh-1.rs b/src/test/ui/numbers-arithmetic/overflowing-lsh-1.rs
new file mode 100644
index 00000000000..e5ce8033639
--- /dev/null
+++ b/src/test/ui/numbers-arithmetic/overflowing-lsh-1.rs
@@ -0,0 +1,9 @@
+// build-fail
+// compile-flags: -C debug-assertions
+
+#![deny(arithmetic_overflow, const_err)]
+
+fn main() {
+    let _x = 1_i32 << 32;
+    //~^ ERROR: this arithmetic operation will overflow
+}
diff --git a/src/test/ui/numbers-arithmetic/overflowing-lsh-1.stderr b/src/test/ui/numbers-arithmetic/overflowing-lsh-1.stderr
new file mode 100644
index 00000000000..54008d33968
--- /dev/null
+++ b/src/test/ui/numbers-arithmetic/overflowing-lsh-1.stderr
@@ -0,0 +1,14 @@
+error: this arithmetic operation will overflow
+  --> $DIR/overflowing-lsh-1.rs:7:14
+   |
+LL |     let _x = 1_i32 << 32;
+   |              ^^^^^^^^^^^ attempt to shift left with overflow
+   |
+note: the lint level is defined here
+  --> $DIR/overflowing-lsh-1.rs:4:9
+   |
+LL | #![deny(arithmetic_overflow, const_err)]
+   |         ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/numbers-arithmetic/overflowing-lsh-2.rs b/src/test/ui/numbers-arithmetic/overflowing-lsh-2.rs
new file mode 100644
index 00000000000..7fd3407a056
--- /dev/null
+++ b/src/test/ui/numbers-arithmetic/overflowing-lsh-2.rs
@@ -0,0 +1,9 @@
+// build-fail
+// compile-flags: -C debug-assertions
+
+#![deny(arithmetic_overflow, const_err)]
+
+fn main() {
+    let _x = 1 << -1;
+    //~^ ERROR: this arithmetic operation will overflow
+}
diff --git a/src/test/ui/numbers-arithmetic/overflowing-lsh-2.stderr b/src/test/ui/numbers-arithmetic/overflowing-lsh-2.stderr
new file mode 100644
index 00000000000..872e71bb737
--- /dev/null
+++ b/src/test/ui/numbers-arithmetic/overflowing-lsh-2.stderr
@@ -0,0 +1,14 @@
+error: this arithmetic operation will overflow
+  --> $DIR/overflowing-lsh-2.rs:7:14
+   |
+LL |     let _x = 1 << -1;
+   |              ^^^^^^^ attempt to shift left with overflow
+   |
+note: the lint level is defined here
+  --> $DIR/overflowing-lsh-2.rs:4:9
+   |
+LL | #![deny(arithmetic_overflow, const_err)]
+   |         ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/numbers-arithmetic/overflowing-lsh-3.rs b/src/test/ui/numbers-arithmetic/overflowing-lsh-3.rs
new file mode 100644
index 00000000000..e007eb4a2e2
--- /dev/null
+++ b/src/test/ui/numbers-arithmetic/overflowing-lsh-3.rs
@@ -0,0 +1,9 @@
+// build-fail
+// compile-flags: -C debug-assertions
+
+#![deny(arithmetic_overflow, const_err)]
+
+fn main() {
+    let _x = 1_u64 << 64;
+    //~^ ERROR: this arithmetic operation will overflow
+}
diff --git a/src/test/ui/numbers-arithmetic/overflowing-lsh-3.stderr b/src/test/ui/numbers-arithmetic/overflowing-lsh-3.stderr
new file mode 100644
index 00000000000..d55ed4a046c
--- /dev/null
+++ b/src/test/ui/numbers-arithmetic/overflowing-lsh-3.stderr
@@ -0,0 +1,14 @@
+error: this arithmetic operation will overflow
+  --> $DIR/overflowing-lsh-3.rs:7:14
+   |
+LL |     let _x = 1_u64 << 64;
+   |              ^^^^^^^^^^^ attempt to shift left with overflow
+   |
+note: the lint level is defined here
+  --> $DIR/overflowing-lsh-3.rs:4:9
+   |
+LL | #![deny(arithmetic_overflow, const_err)]
+   |         ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/run-fail/overflowing-lsh-4.rs b/src/test/ui/numbers-arithmetic/overflowing-lsh-4.rs
index 0d3912ce13f..738d0133915 100644
--- a/src/test/run-fail/overflowing-lsh-4.rs
+++ b/src/test/ui/numbers-arithmetic/overflowing-lsh-4.rs
@@ -1,15 +1,15 @@
-// error-pattern:thread 'main' panicked at 'attempt to shift left with overflow'
+// build-fail
 // compile-flags: -C debug-assertions
 
 // This function is checking that our automatic truncation does not
 // sidestep the overflow checking.
 
-#![warn(arithmetic_overflow)]
-#![warn(const_err)]
+#![deny(arithmetic_overflow, const_err)]
 
 fn main() {
     // this signals overflow when checking is on
     let x = 1_i8 << 17;
+    //~^ ERROR: this arithmetic operation will overflow
 
     // ... but when checking is off, the fallback will truncate the
     // input to its lower three bits (= 1). Note that this is *not*
diff --git a/src/test/ui/numbers-arithmetic/overflowing-lsh-4.stderr b/src/test/ui/numbers-arithmetic/overflowing-lsh-4.stderr
new file mode 100644
index 00000000000..1ef8dd3466c
--- /dev/null
+++ b/src/test/ui/numbers-arithmetic/overflowing-lsh-4.stderr
@@ -0,0 +1,14 @@
+error: this arithmetic operation will overflow
+  --> $DIR/overflowing-lsh-4.rs:11:13
+   |
+LL |     let x = 1_i8 << 17;
+   |             ^^^^^^^^^^ attempt to shift left with overflow
+   |
+note: the lint level is defined here
+  --> $DIR/overflowing-lsh-4.rs:7:9
+   |
+LL | #![deny(arithmetic_overflow, const_err)]
+   |         ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/run-fail/overflowing-mul.rs b/src/test/ui/numbers-arithmetic/overflowing-mul.rs
index 2dfc9bb5ae4..34ab5d8fad5 100644
--- a/src/test/run-fail/overflowing-mul.rs
+++ b/src/test/ui/numbers-arithmetic/overflowing-mul.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:thread 'main' panicked at 'attempt to multiply with overflow'
+// ignore-emscripten no processes
 // compile-flags: -C debug-assertions
 
 #![allow(arithmetic_overflow)]
diff --git a/src/test/run-fail/overflowing-neg.rs b/src/test/ui/numbers-arithmetic/overflowing-neg.rs
index f512aa35bed..fe77544641c 100644
--- a/src/test/run-fail/overflowing-neg.rs
+++ b/src/test/ui/numbers-arithmetic/overflowing-neg.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:thread 'main' panicked at 'attempt to negate with overflow'
+// ignore-emscripten no processes
 // compile-flags: -C debug-assertions
 
 #![allow(arithmetic_overflow)]
diff --git a/src/test/run-fail/overflowing-pow-signed.rs b/src/test/ui/numbers-arithmetic/overflowing-pow-signed.rs
index c539c685faf..b59efe6f212 100644
--- a/src/test/run-fail/overflowing-pow-signed.rs
+++ b/src/test/ui/numbers-arithmetic/overflowing-pow-signed.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:thread 'main' panicked at 'attempt to multiply with overflow'
+// ignore-emscripten no processes
 // compile-flags: -C debug-assertions
 
 fn main() {
diff --git a/src/test/run-fail/overflowing-pow-unsigned.rs b/src/test/ui/numbers-arithmetic/overflowing-pow-unsigned.rs
index 1d4fa3b5c7e..f2643c16463 100644
--- a/src/test/run-fail/overflowing-pow-unsigned.rs
+++ b/src/test/ui/numbers-arithmetic/overflowing-pow-unsigned.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:thread 'main' panicked at 'attempt to multiply with overflow'
+// ignore-emscripten no processes
 // compile-flags: -C debug-assertions
 
 fn main() {
diff --git a/src/test/ui/numbers-arithmetic/overflowing-rsh-1.rs b/src/test/ui/numbers-arithmetic/overflowing-rsh-1.rs
new file mode 100644
index 00000000000..f1488cf8559
--- /dev/null
+++ b/src/test/ui/numbers-arithmetic/overflowing-rsh-1.rs
@@ -0,0 +1,9 @@
+// build-fail
+// compile-flags: -C debug-assertions
+
+#![deny(arithmetic_overflow, const_err)]
+
+fn main() {
+    let _x = -1_i32 >> 32;
+    //~^ ERROR: this arithmetic operation will overflow
+}
diff --git a/src/test/ui/numbers-arithmetic/overflowing-rsh-1.stderr b/src/test/ui/numbers-arithmetic/overflowing-rsh-1.stderr
new file mode 100644
index 00000000000..236303e2e9a
--- /dev/null
+++ b/src/test/ui/numbers-arithmetic/overflowing-rsh-1.stderr
@@ -0,0 +1,14 @@
+error: this arithmetic operation will overflow
+  --> $DIR/overflowing-rsh-1.rs:7:14
+   |
+LL |     let _x = -1_i32 >> 32;
+   |              ^^^^^^^^^^^^ attempt to shift right with overflow
+   |
+note: the lint level is defined here
+  --> $DIR/overflowing-rsh-1.rs:4:9
+   |
+LL | #![deny(arithmetic_overflow, const_err)]
+   |         ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/numbers-arithmetic/overflowing-rsh-2.rs b/src/test/ui/numbers-arithmetic/overflowing-rsh-2.rs
new file mode 100644
index 00000000000..39127b9703b
--- /dev/null
+++ b/src/test/ui/numbers-arithmetic/overflowing-rsh-2.rs
@@ -0,0 +1,9 @@
+// build-fail
+// compile-flags: -C debug-assertions
+
+#![deny(arithmetic_overflow, const_err)]
+
+fn main() {
+    let _x = -1_i32 >> -1;
+    //~^ ERROR: this arithmetic operation will overflow
+}
diff --git a/src/test/ui/numbers-arithmetic/overflowing-rsh-2.stderr b/src/test/ui/numbers-arithmetic/overflowing-rsh-2.stderr
new file mode 100644
index 00000000000..981c8986f76
--- /dev/null
+++ b/src/test/ui/numbers-arithmetic/overflowing-rsh-2.stderr
@@ -0,0 +1,14 @@
+error: this arithmetic operation will overflow
+  --> $DIR/overflowing-rsh-2.rs:7:14
+   |
+LL |     let _x = -1_i32 >> -1;
+   |              ^^^^^^^^^^^^ attempt to shift right with overflow
+   |
+note: the lint level is defined here
+  --> $DIR/overflowing-rsh-2.rs:4:9
+   |
+LL | #![deny(arithmetic_overflow, const_err)]
+   |         ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/numbers-arithmetic/overflowing-rsh-3.rs b/src/test/ui/numbers-arithmetic/overflowing-rsh-3.rs
new file mode 100644
index 00000000000..8ee6dde93ea
--- /dev/null
+++ b/src/test/ui/numbers-arithmetic/overflowing-rsh-3.rs
@@ -0,0 +1,9 @@
+// build-fail
+// compile-flags: -C debug-assertions
+
+#![deny(arithmetic_overflow, const_err)]
+
+fn main() {
+    let _x = -1_i64 >> 64;
+    //~^ ERROR: this arithmetic operation will overflow
+}
diff --git a/src/test/ui/numbers-arithmetic/overflowing-rsh-3.stderr b/src/test/ui/numbers-arithmetic/overflowing-rsh-3.stderr
new file mode 100644
index 00000000000..c2994503f0e
--- /dev/null
+++ b/src/test/ui/numbers-arithmetic/overflowing-rsh-3.stderr
@@ -0,0 +1,14 @@
+error: this arithmetic operation will overflow
+  --> $DIR/overflowing-rsh-3.rs:7:14
+   |
+LL |     let _x = -1_i64 >> 64;
+   |              ^^^^^^^^^^^^ attempt to shift right with overflow
+   |
+note: the lint level is defined here
+  --> $DIR/overflowing-rsh-3.rs:4:9
+   |
+LL | #![deny(arithmetic_overflow, const_err)]
+   |         ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/run-fail/overflowing-rsh-4.rs b/src/test/ui/numbers-arithmetic/overflowing-rsh-4.rs
index 1877d5c9685..ce7f818e330 100644
--- a/src/test/run-fail/overflowing-rsh-4.rs
+++ b/src/test/ui/numbers-arithmetic/overflowing-rsh-4.rs
@@ -1,15 +1,15 @@
-// error-pattern:thread 'main' panicked at 'attempt to shift right with overflow'
+// build-fail
 // compile-flags: -C debug-assertions
 
 // This function is checking that our (type-based) automatic
 // truncation does not sidestep the overflow checking.
 
-#![warn(arithmetic_overflow)]
-#![warn(const_err)]
+#![deny(arithmetic_overflow, const_err)]
 
 fn main() {
     // this signals overflow when checking is on
     let x = 2_i8 >> 17;
+    //~^ ERROR: this arithmetic operation will overflow
 
     // ... but when checking is off, the fallback will truncate the
     // input to its lower three bits (= 1). Note that this is *not*
diff --git a/src/test/ui/numbers-arithmetic/overflowing-rsh-4.stderr b/src/test/ui/numbers-arithmetic/overflowing-rsh-4.stderr
new file mode 100644
index 00000000000..3db1da06dbe
--- /dev/null
+++ b/src/test/ui/numbers-arithmetic/overflowing-rsh-4.stderr
@@ -0,0 +1,14 @@
+error: this arithmetic operation will overflow
+  --> $DIR/overflowing-rsh-4.rs:11:13
+   |
+LL |     let x = 2_i8 >> 17;
+   |             ^^^^^^^^^^ attempt to shift right with overflow
+   |
+note: the lint level is defined here
+  --> $DIR/overflowing-rsh-4.rs:7:9
+   |
+LL | #![deny(arithmetic_overflow, const_err)]
+   |         ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/numbers-arithmetic/overflowing-rsh-5.rs b/src/test/ui/numbers-arithmetic/overflowing-rsh-5.rs
new file mode 100644
index 00000000000..88928c99596
--- /dev/null
+++ b/src/test/ui/numbers-arithmetic/overflowing-rsh-5.rs
@@ -0,0 +1,9 @@
+// build-fail
+// compile-flags: -C debug-assertions
+
+#![deny(arithmetic_overflow, const_err)]
+
+fn main() {
+    let _n = 1i64 >> [64][0];
+    //~^ ERROR: this arithmetic operation will overflow
+}
diff --git a/src/test/ui/numbers-arithmetic/overflowing-rsh-5.stderr b/src/test/ui/numbers-arithmetic/overflowing-rsh-5.stderr
new file mode 100644
index 00000000000..bd3eae82977
--- /dev/null
+++ b/src/test/ui/numbers-arithmetic/overflowing-rsh-5.stderr
@@ -0,0 +1,14 @@
+error: this arithmetic operation will overflow
+  --> $DIR/overflowing-rsh-5.rs:7:14
+   |
+LL |     let _n = 1i64 >> [64][0];
+   |              ^^^^^^^^^^^^^^^ attempt to shift right with overflow
+   |
+note: the lint level is defined here
+  --> $DIR/overflowing-rsh-5.rs:4:9
+   |
+LL | #![deny(arithmetic_overflow, const_err)]
+   |         ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/numbers-arithmetic/overflowing-rsh-6.rs b/src/test/ui/numbers-arithmetic/overflowing-rsh-6.rs
new file mode 100644
index 00000000000..88928c99596
--- /dev/null
+++ b/src/test/ui/numbers-arithmetic/overflowing-rsh-6.rs
@@ -0,0 +1,9 @@
+// build-fail
+// compile-flags: -C debug-assertions
+
+#![deny(arithmetic_overflow, const_err)]
+
+fn main() {
+    let _n = 1i64 >> [64][0];
+    //~^ ERROR: this arithmetic operation will overflow
+}
diff --git a/src/test/ui/numbers-arithmetic/overflowing-rsh-6.stderr b/src/test/ui/numbers-arithmetic/overflowing-rsh-6.stderr
new file mode 100644
index 00000000000..5d76639fb50
--- /dev/null
+++ b/src/test/ui/numbers-arithmetic/overflowing-rsh-6.stderr
@@ -0,0 +1,14 @@
+error: this arithmetic operation will overflow
+  --> $DIR/overflowing-rsh-6.rs:7:14
+   |
+LL |     let _n = 1i64 >> [64][0];
+   |              ^^^^^^^^^^^^^^^ attempt to shift right with overflow
+   |
+note: the lint level is defined here
+  --> $DIR/overflowing-rsh-6.rs:4:9
+   |
+LL | #![deny(arithmetic_overflow, const_err)]
+   |         ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/run-fail/overflowing-sub.rs b/src/test/ui/numbers-arithmetic/overflowing-sub.rs
index fb096c31957..66685ac961a 100644
--- a/src/test/run-fail/overflowing-sub.rs
+++ b/src/test/ui/numbers-arithmetic/overflowing-sub.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:thread 'main' panicked at 'attempt to subtract with overflow'
+// ignore-emscripten no processes
 // compile-flags: -C debug-assertions
 
 #![allow(arithmetic_overflow)]
diff --git a/src/test/run-fail/promoted_overflow.rs b/src/test/ui/numbers-arithmetic/promoted_overflow.rs
index 3c42da4b1d8..da59e81ed6b 100644
--- a/src/test/run-fail/promoted_overflow.rs
+++ b/src/test/ui/numbers-arithmetic/promoted_overflow.rs
@@ -1,5 +1,6 @@
 #![allow(arithmetic_overflow)]
 
+// run-fail
 // error-pattern: overflow
 // compile-flags: -C overflow-checks=yes
 
diff --git a/src/test/run-fail/unwind-interleaved.rs b/src/test/ui/panic-runtime/unwind-interleaved.rs
index c163678ae98..a8b3f349309 100644
--- a/src/test/run-fail/unwind-interleaved.rs
+++ b/src/test/ui/panic-runtime/unwind-interleaved.rs
@@ -1,4 +1,6 @@
-// error-pattern:fail
+// run-fail
+// error-pattern:explicit panic
+// ignore-emscripten no processes
 
 fn a() {}
 
diff --git a/src/test/run-fail/unwind-rec.rs b/src/test/ui/panic-runtime/unwind-rec.rs
index 83ac19ff4a5..a9b7ee8ec7d 100644
--- a/src/test/run-fail/unwind-rec.rs
+++ b/src/test/ui/panic-runtime/unwind-rec.rs
@@ -1,5 +1,6 @@
-// error-pattern:fail
-
+// run-fail
+// error-pattern:explicit panic
+// ignore-emscripten no processes
 
 fn build() -> Vec<isize> {
     panic!();
diff --git a/src/test/run-fail/unwind-rec2.rs b/src/test/ui/panic-runtime/unwind-rec2.rs
index 4dfc282b6c0..a130f9e879f 100644
--- a/src/test/run-fail/unwind-rec2.rs
+++ b/src/test/ui/panic-runtime/unwind-rec2.rs
@@ -1,5 +1,6 @@
-// error-pattern:fail
-
+// run-fail
+// error-pattern:explicit panic
+// ignore-emscripten no processes
 
 fn build1() -> Vec<isize> {
     vec![0, 0, 0, 0, 0, 0, 0]
diff --git a/src/test/ui/panic-runtime/unwind-unique.rs b/src/test/ui/panic-runtime/unwind-unique.rs
new file mode 100644
index 00000000000..d66e39110ea
--- /dev/null
+++ b/src/test/ui/panic-runtime/unwind-unique.rs
@@ -0,0 +1,12 @@
+// run-fail
+// error-pattern:explicit panic
+// ignore-emscripten no processes
+
+fn failfn() {
+    panic!();
+}
+
+fn main() {
+    Box::new(0);
+    failfn();
+}
diff --git a/src/test/run-fail/args-panic.rs b/src/test/ui/panics/args-panic.rs
index 9a62652dde1..322054caf11 100644
--- a/src/test/run-fail/args-panic.rs
+++ b/src/test/ui/panics/args-panic.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:meep
+// ignore-emscripten no processes
 
 #![feature(box_syntax)]
 
diff --git a/src/test/run-fail/doublepanic.rs b/src/test/ui/panics/doublepanic.rs
index 10d303e491e..c1fcc875c36 100644
--- a/src/test/run-fail/doublepanic.rs
+++ b/src/test/ui/panics/doublepanic.rs
@@ -1,6 +1,9 @@
 #![allow(unreachable_code)]
 
+// run-fail
 // error-pattern:One
+// ignore-emscripten no processes
+
 fn main() {
     panic!("One");
     panic!("Two");
diff --git a/src/test/run-fail/explicit-panic-msg.rs b/src/test/ui/panics/explicit-panic-msg.rs
index 35e0518b9be..1789e2e62c8 100644
--- a/src/test/run-fail/explicit-panic-msg.rs
+++ b/src/test/ui/panics/explicit-panic-msg.rs
@@ -1,7 +1,10 @@
 #![allow(unused_assignments)]
 #![allow(unused_variables)]
 
+// run-fail
 // error-pattern:wooooo
+// ignore-emscripten no processes
+
 fn main() {
     let mut a = 1;
     if 1 == 1 {
diff --git a/src/test/run-fail/explicit-panic.rs b/src/test/ui/panics/explicit-panic.rs
index 11ea6b41221..27c73d3493c 100644
--- a/src/test/run-fail/explicit-panic.rs
+++ b/src/test/ui/panics/explicit-panic.rs
@@ -1,4 +1,7 @@
+// run-fail
 // error-pattern:explicit
+// ignore-emscripten no processes
+
 fn main() {
     panic!();
 }
diff --git a/src/test/run-fail/fmt-panic.rs b/src/test/ui/panics/fmt-panic.rs
index 5749991914c..87fb2e6dd54 100644
--- a/src/test/run-fail/fmt-panic.rs
+++ b/src/test/ui/panics/fmt-panic.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:meh
+// ignore-emscripten no processes
 
 fn main() {
     let str_var: String = "meh".to_string();
diff --git a/src/test/run-fail/main-panic.rs b/src/test/ui/panics/main-panic.rs
index 3a9409562db..023ab470125 100644
--- a/src/test/run-fail/main-panic.rs
+++ b/src/test/ui/panics/main-panic.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:thread 'main' panicked at
+// ignore-emscripten no processes
 
 fn main() {
     panic!()
diff --git a/src/test/run-fail/panic-arg.rs b/src/test/ui/panics/panic-arg.rs
index c164ff94630..f7c2dbb096f 100644
--- a/src/test/run-fail/panic-arg.rs
+++ b/src/test/ui/panics/panic-arg.rs
@@ -1,4 +1,7 @@
+// run-fail
 // error-pattern:woe
+// ignore-emscripten no processes
+
 fn f(a: isize) {
     println!("{}", a);
 }
diff --git a/src/test/run-fail/panic-macro-any-wrapped.rs b/src/test/ui/panics/panic-macro-any-wrapped.rs
index 83eb39a538f..80c87c6f32c 100644
--- a/src/test/run-fail/panic-macro-any-wrapped.rs
+++ b/src/test/ui/panics/panic-macro-any-wrapped.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:panicked at 'Box<Any>'
+// ignore-emscripten no processes
 
 fn main() {
     panic!(Box::new(612_i64));
diff --git a/src/test/ui/panics/panic-macro-any.rs b/src/test/ui/panics/panic-macro-any.rs
new file mode 100644
index 00000000000..ffc7114c1f5
--- /dev/null
+++ b/src/test/ui/panics/panic-macro-any.rs
@@ -0,0 +1,9 @@
+// run-fail
+// error-pattern:panicked at 'Box<Any>'
+// ignore-emscripten no processes
+
+#![feature(box_syntax)]
+
+fn main() {
+    panic!(box 413 as Box<dyn std::any::Any + Send>);
+}
diff --git a/src/test/run-fail/panic-macro-explicit.rs b/src/test/ui/panics/panic-macro-explicit.rs
index f632034807c..ac4d6f8128b 100644
--- a/src/test/run-fail/panic-macro-explicit.rs
+++ b/src/test/ui/panics/panic-macro-explicit.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:panicked at 'explicit panic'
+// ignore-emscripten no processes
 
 fn main() {
     panic!();
diff --git a/src/test/run-fail/panic-macro-fmt.rs b/src/test/ui/panics/panic-macro-fmt.rs
index 658ae56e7e4..a755ebc0f4e 100644
--- a/src/test/run-fail/panic-macro-fmt.rs
+++ b/src/test/ui/panics/panic-macro-fmt.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:panicked at 'test-fail-fmt 42 rust'
+// ignore-emscripten no processes
 
 fn main() {
     panic!("test-fail-fmt {} {}", 42, "rust");
diff --git a/src/test/run-fail/panic-macro-owned.rs b/src/test/ui/panics/panic-macro-owned.rs
index 9b935717638..b898fde77a3 100644
--- a/src/test/run-fail/panic-macro-owned.rs
+++ b/src/test/ui/panics/panic-macro-owned.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:panicked at 'test-fail-owned'
+// ignore-emscripten no processes
 
 fn main() {
     panic!("test-fail-owned");
diff --git a/src/test/run-fail/panic-macro-static.rs b/src/test/ui/panics/panic-macro-static.rs
index 31ac488beb2..a1d467cbfb5 100644
--- a/src/test/run-fail/panic-macro-static.rs
+++ b/src/test/ui/panics/panic-macro-static.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:panicked at 'test-fail-static'
+// ignore-emscripten no processes
 
 fn main() {
     panic!("test-fail-static");
diff --git a/src/test/run-fail/panic-main.rs b/src/test/ui/panics/panic-main.rs
index 881eb7b5823..87df7688f0b 100644
--- a/src/test/run-fail/panic-main.rs
+++ b/src/test/ui/panics/panic-main.rs
@@ -1,4 +1,7 @@
+// run-fail
 // error-pattern:moop
+// ignore-emscripten no processes
+
 fn main() {
     panic!("moop");
 }
diff --git a/src/test/run-fail/panic-parens.rs b/src/test/ui/panics/panic-parens.rs
index e7f98e58c4f..59ab5444649 100644
--- a/src/test/run-fail/panic-parens.rs
+++ b/src/test/ui/panics/panic-parens.rs
@@ -1,6 +1,9 @@
 // Fail macros without arguments need to be disambiguated in
 // certain positions
+
+// run-fail
 // error-pattern:oops
+// ignore-emscripten no processes
 
 fn bigpanic() {
     while (panic!("oops")) {
diff --git a/src/test/run-fail/panic-set-handler.rs b/src/test/ui/panics/panic-set-handler.rs
index ea2b152c6c4..3c00183e253 100644
--- a/src/test/run-fail/panic-set-handler.rs
+++ b/src/test/ui/panics/panic-set-handler.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:greetings from the panic handler
+// ignore-emscripten no processes
 
 use std::panic;
 
diff --git a/src/test/run-fail/panic-set-unset-handler.rs b/src/test/ui/panics/panic-set-unset-handler.rs
index f8809c2f388..dde0c72f765 100644
--- a/src/test/run-fail/panic-set-unset-handler.rs
+++ b/src/test/ui/panics/panic-set-unset-handler.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:thread 'main' panicked at 'foobar'
+// ignore-emscripten no processes
 
 use std::panic;
 
diff --git a/src/test/run-fail/panic-take-handler-nop.rs b/src/test/ui/panics/panic-take-handler-nop.rs
index bb191a38f84..41cbac97c44 100644
--- a/src/test/run-fail/panic-take-handler-nop.rs
+++ b/src/test/ui/panics/panic-take-handler-nop.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:thread 'main' panicked at 'foobar'
+// ignore-emscripten no processes
 
 use std::panic;
 
diff --git a/src/test/run-fail/panic-task-name-none.rs b/src/test/ui/panics/panic-task-name-none.rs
index c7f504046ba..4e95fb5bdb8 100644
--- a/src/test/run-fail/panic-task-name-none.rs
+++ b/src/test/ui/panics/panic-task-name-none.rs
@@ -1,3 +1,4 @@
+// run-fail
 // error-pattern:thread '<unnamed>' panicked at 'test'
 // ignore-emscripten Needs threads
 
diff --git a/src/test/run-fail/panic-task-name-owned.rs b/src/test/ui/panics/panic-task-name-owned.rs
index 58f76ff787f..f85be7bb8e2 100644
--- a/src/test/run-fail/panic-task-name-owned.rs
+++ b/src/test/ui/panics/panic-task-name-owned.rs
@@ -1,3 +1,4 @@
+// run-fail
 // error-pattern:thread 'owned name' panicked at 'test'
 // ignore-emscripten Needs threads.
 
diff --git a/src/test/run-fail/panic.rs b/src/test/ui/panics/panic.rs
index 95f20dedad2..b6227a582ce 100644
--- a/src/test/run-fail/panic.rs
+++ b/src/test/ui/panics/panic.rs
@@ -1,4 +1,7 @@
+// run-fail
 // error-pattern:1 == 2
+// ignore-emscripten no processes
+
 fn main() {
     assert!(1 == 2);
 }
diff --git a/src/test/run-fail/result-get-panic.rs b/src/test/ui/panics/result-get-panic.rs
index cddf20ee49d..461f30b9134 100644
--- a/src/test/run-fail/result-get-panic.rs
+++ b/src/test/ui/panics/result-get-panic.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:called `Result::unwrap()` on an `Err` value
+// ignore-emscripten no processes
 
 use std::result::Result::Err;
 
diff --git a/src/test/run-fail/test-panic.rs b/src/test/ui/panics/test-panic.rs
index 92f5146b710..85c9279cdf2 100644
--- a/src/test/run-fail/test-panic.rs
+++ b/src/test/ui/panics/test-panic.rs
@@ -1,5 +1,5 @@
+// run-fail
 // check-stdout
-// error-pattern:thread 'test_foo' panicked at
 // compile-flags: --test
 // ignore-emscripten
 
diff --git a/src/test/run-fail/test-should-fail-bad-message.rs b/src/test/ui/panics/test-should-fail-bad-message.rs
index 3c69bb07d3b..701f2677648 100644
--- a/src/test/run-fail/test-should-fail-bad-message.rs
+++ b/src/test/ui/panics/test-should-fail-bad-message.rs
@@ -1,5 +1,5 @@
+// run-fail
 // check-stdout
-// error-pattern:thread 'test_foo' panicked at
 // compile-flags: --test
 // ignore-emscripten
 
diff --git a/src/test/run-fail/test-should-panic-bad-message.rs b/src/test/ui/panics/test-should-panic-bad-message.rs
index b73d4d7377a..a82c4e1440a 100644
--- a/src/test/run-fail/test-should-panic-bad-message.rs
+++ b/src/test/ui/panics/test-should-panic-bad-message.rs
@@ -1,7 +1,8 @@
+// run-fail
 // compile-flags: --test
-
-// error-pattern:panicked at 'bar'
 // check-stdout
+// ignore-emscripten no processes
+
 #[test]
 #[should_panic(expected = "foo")]
 pub fn test_bar() {
diff --git a/src/test/run-fail/test-should-panic-no-message.rs b/src/test/ui/panics/test-should-panic-no-message.rs
index b18389ec744..13f67a41cdd 100644
--- a/src/test/run-fail/test-should-panic-no-message.rs
+++ b/src/test/ui/panics/test-should-panic-no-message.rs
@@ -1,7 +1,8 @@
+// run-fail
 // compile-flags: --test
-
-// error-pattern:panicked at 'explicit panic'
 // check-stdout
+// ignore-emscripten no processes
+
 #[test]
 #[should_panic(expected = "foo")]
 pub fn test_explicit() {
diff --git a/src/test/run-fail/unique-panic.rs b/src/test/ui/panics/unique-panic.rs
index adefd796af4..22e0d63d594 100644
--- a/src/test/run-fail/unique-panic.rs
+++ b/src/test/ui/panics/unique-panic.rs
@@ -1,3 +1,4 @@
+// run-fail
 // error-pattern: panic
 
 fn main() {
diff --git a/src/test/run-fail/while-body-panics.rs b/src/test/ui/panics/while-body-panics.rs
index 76acb4ba42d..2c05eb389cc 100644
--- a/src/test/run-fail/while-body-panics.rs
+++ b/src/test/ui/panics/while-body-panics.rs
@@ -1,6 +1,9 @@
 #![allow(while_true)]
 
+// run-fail
 // error-pattern:quux
+// ignore-emscripten no processes
+
 fn main() {
     let _x: isize = {
         while true {
diff --git a/src/test/run-fail/while-panic.rs b/src/test/ui/panics/while-panic.rs
index a0827591729..857f65a2252 100644
--- a/src/test/run-fail/while-panic.rs
+++ b/src/test/ui/panics/while-panic.rs
@@ -1,6 +1,9 @@
 #![allow(while_true)]
 
+// run-fail
 // error-pattern:giraffe
+// ignore-emscripten no processes
+
 fn main() {
     panic!({
         while true {
diff --git a/src/test/run-fail/tls-exit-status.rs b/src/test/ui/process/tls-exit-status.rs
index f15fd4f6894..36d6aff9e77 100644
--- a/src/test/run-fail/tls-exit-status.rs
+++ b/src/test/ui/process/tls-exit-status.rs
@@ -1,6 +1,8 @@
+// run-fail
 // error-pattern:nonzero
 // exec-env:RUST_NEWRT=1
 // ignore-cloudabi no std::env
+// ignore-emscripten no processes
 
 use std::env;
 
diff --git a/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs b/src/test/ui/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs
index 796729ac4cc..10dc6115dcb 100644
--- a/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs
+++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs
@@ -1,5 +1,7 @@
+// run-fail
 // error-pattern:returned Box<dyn Error> from main()
 // failure-status: 1
+// ignore-emscripten no processes
 
 use std::error::Error;
 use std::io;
diff --git a/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-never.rs b/src/test/ui/rfc-1937-termination-trait/termination-trait-for-never.rs
index cb37b8e0670..faf2526c8d8 100644
--- a/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-never.rs
+++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-for-never.rs
@@ -1,4 +1,6 @@
+// run-fail
 // error-pattern:oh, dear
+// ignore-emscripten no processes
 
 fn main() -> ! {
     panic!("oh, dear");
diff --git a/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-result-box-error_err.rs b/src/test/ui/rfc-1937-termination-trait/termination-trait-for-result-box-error_err.rs
index 2f3a73a30ad..6a625fb05e8 100644
--- a/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-result-box-error_err.rs
+++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-for-result-box-error_err.rs
@@ -1,5 +1,7 @@
+// run-fail
 // error-pattern:returned Box<Error> from main()
 // failure-status: 1
+// ignore-emscripten no processes
 
 use std::io::{Error, ErrorKind};
 
diff --git a/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-str.rs b/src/test/ui/rfc-1937-termination-trait/termination-trait-for-str.rs
index bd6fa8af935..94f16c6fd02 100644
--- a/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-str.rs
+++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-for-str.rs
@@ -1,5 +1,7 @@
+// run-fail
 // error-pattern: An error message for you
 // failure-status: 1
+// ignore-emscripten no processes
 
 fn main() -> Result<(), &'static str> {
     Err("An error message for you")
diff --git a/src/test/run-fail/str-overrun.rs b/src/test/ui/str/str-overrun.rs
index e566308a087..a3ec8941322 100644
--- a/src/test/run-fail/str-overrun.rs
+++ b/src/test/ui/str/str-overrun.rs
@@ -1,4 +1,7 @@
+// run-fail
 // error-pattern:index out of bounds: the len is 5 but the index is 5
+// ignore-emscripten no processes
+
 fn main() {
     let s: String = "hello".to_string();
 
diff --git a/src/test/run-fail/rhs-type.rs b/src/test/ui/structs/rhs-type.rs
index 6efbeadd704..c48e7c08ed2 100644
--- a/src/test/run-fail/rhs-type.rs
+++ b/src/test/ui/structs/rhs-type.rs
@@ -1,6 +1,9 @@
 // Tests that codegen treats the rhs of pth's decl
 // as a _|_-typed thing, not a str-typed thing
+
+// run-fail
 // error-pattern:bye
+// ignore-emscripten no processes
 
 #![allow(unreachable_code)]
 #![allow(unused_variables)]
diff --git a/src/test/run-fail/run-unexported-tests.rs b/src/test/ui/test-attrs/run-unexported-tests.rs
index 11e100e716e..f533a3ef885 100644
--- a/src/test/run-fail/run-unexported-tests.rs
+++ b/src/test/ui/test-attrs/run-unexported-tests.rs
@@ -1,4 +1,4 @@
-// error-pattern:ran an unexported test
+// run-fail
 // compile-flags:--test
 // check-stdout
 
diff --git a/src/test/run-fail/task-spawn-barefn.rs b/src/test/ui/threads-sendsync/task-spawn-barefn.rs
index 497c5ea7180..e5b899e0af9 100644
--- a/src/test/run-fail/task-spawn-barefn.rs
+++ b/src/test/ui/threads-sendsync/task-spawn-barefn.rs
@@ -1,3 +1,4 @@
+// run-fail
 // error-pattern:Ensure that the child thread runs by panicking
 // ignore-emscripten Needs threads.
 
diff --git a/src/test/run-fail/test-tasks-invalid-value.rs b/src/test/ui/threads-sendsync/test-tasks-invalid-value.rs
index 2dae1b4592c..6411421429c 100644
--- a/src/test/run-fail/test-tasks-invalid-value.rs
+++ b/src/test/ui/threads-sendsync/test-tasks-invalid-value.rs
@@ -1,6 +1,7 @@
 // This checks that RUST_TEST_THREADS not being 1, 2, ... is detected
 // properly.
 
+// run-fail
 // error-pattern:should be a positive integer
 // compile-flags: --test
 // exec-env:RUST_TEST_THREADS=foo
diff --git a/src/test/run-fail/vec-overrun.rs b/src/test/ui/vec/vec-overrun.rs
index 2be945f736c..bdc7d507d53 100644
--- a/src/test/run-fail/vec-overrun.rs
+++ b/src/test/ui/vec/vec-overrun.rs
@@ -1,5 +1,6 @@
+// run-fail
 // error-pattern:index out of bounds: the len is 1 but the index is 2
-
+// ignore-emscripten no processes
 
 fn main() {
     let v: Vec<isize> = vec![10];
diff --git a/src/tools/clippy/clippy_lints/src/bytecount.rs b/src/tools/clippy/clippy_lints/src/bytecount.rs
index 91d3e47d787..278d043732f 100644
--- a/src/tools/clippy/clippy_lints/src/bytecount.rs
+++ b/src/tools/clippy/clippy_lints/src/bytecount.rs
@@ -3,12 +3,13 @@ use crate::utils::{
     span_lint_and_sugg, walk_ptrs_ty,
 };
 use if_chain::if_chain;
-use rustc_ast::ast::{Name, UintTy};
+use rustc_ast::ast::{UintTy};
 use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, UnOp};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_span::Symbol;
 
 declare_clippy_lint! {
     /// **What it does:** Checks for naive byte counts
@@ -95,11 +96,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ByteCount {
     }
 }
 
-fn check_arg(name: Name, arg: Name, needle: &Expr<'_>) -> bool {
+fn check_arg(name: Symbol, arg: Symbol, needle: &Expr<'_>) -> bool {
     name == arg && !contains_name(name, needle)
 }
 
-fn get_path_name(expr: &Expr<'_>) -> Option<Name> {
+fn get_path_name(expr: &Expr<'_>) -> Option<Symbol> {
     match expr.kind {
         ExprKind::Box(ref e) | ExprKind::AddrOf(BorrowKind::Ref, _, ref e) | ExprKind::Unary(UnOp::UnDeref, ref e) => {
             get_path_name(e)
diff --git a/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs b/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs
index 1ebfb3c8162..475610dda47 100644
--- a/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs
+++ b/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs
@@ -2,11 +2,12 @@
 
 use crate::utils::span_lint_and_then;
 use crate::utils::sugg::DiagnosticBuilderExt;
-use rustc_ast::ast::{Attribute, Name};
+use rustc_ast::ast::Attribute;
 use rustc_errors::Applicability;
 use rustc_hir::{TraitFn, TraitItem, TraitItemKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_span::Symbol;
 
 declare_clippy_lint! {
     /// **What it does:** Checks for `#[inline]` on trait methods without bodies
@@ -38,7 +39,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InlineFnWithoutBody {
     }
 }
 
-fn check_attrs(cx: &LateContext<'_, '_>, name: Name, attrs: &[Attribute]) {
+fn check_attrs(cx: &LateContext<'_, '_>, name: Symbol, attrs: &[Attribute]) {
     for attr in attrs {
         if !attr.check_name(sym!(inline)) {
             continue;
diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs
index 1d86ca9696f..2ec0b5a8d6f 100644
--- a/src/tools/clippy/clippy_lints/src/len_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/len_zero.rs
@@ -1,5 +1,5 @@
 use crate::utils::{get_item_name, snippet_with_applicability, span_lint, span_lint_and_sugg, walk_ptrs_ty};
-use rustc_ast::ast::{LitKind, Name};
+use rustc_ast::ast::LitKind;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
 use rustc_hir::def_id::DefId;
@@ -7,7 +7,7 @@ use rustc_hir::{AssocItemKind, BinOpKind, Expr, ExprKind, ImplItemRef, Item, Ite
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::source_map::{Span, Spanned};
+use rustc_span::source_map::{Span, Spanned, Symbol};
 
 declare_clippy_lint! {
     /// **What it does:** Checks for getting the length of something via `.len()`
@@ -226,7 +226,7 @@ fn check_cmp(cx: &LateContext<'_, '_>, span: Span, method: &Expr<'_>, lit: &Expr
 fn check_len(
     cx: &LateContext<'_, '_>,
     span: Span,
-    method_name: Name,
+    method_name: Symbol,
     args: &[Expr<'_>],
     lit: &LitKind,
     op: &str,
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index c995be5edc2..1f135cba6e4 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -333,7 +333,7 @@ mod zero_div_zero;
 pub use crate::utils::conf::Conf;
 
 mod reexport {
-    pub use rustc_ast::ast::Name;
+    pub use rustc_span::Symbol as Name;
 }
 
 /// Register all pre expansion lints
diff --git a/src/tools/clippy/clippy_lints/src/map_clone.rs b/src/tools/clippy/clippy_lints/src/map_clone.rs
index 0b346393ac3..0163b3f8dbc 100644
--- a/src/tools/clippy/clippy_lints/src/map_clone.rs
+++ b/src/tools/clippy/clippy_lints/src/map_clone.rs
@@ -3,14 +3,14 @@ use crate::utils::{
     is_copy, is_type_diagnostic_item, match_trait_method, remove_blocks, snippet_with_applicability, span_lint_and_sugg,
 };
 use if_chain::if_chain;
-use rustc_ast::ast::Ident;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::mir::Mutability;
 use rustc_middle::ty;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::source_map::Span;
+use rustc_span::Span;
+use rustc_span::symbol::Ident;
 
 declare_clippy_lint! {
     /// **What it does:** Checks for usage of `iterator.map(|x| x.clone())` and suggests
diff --git a/src/tools/clippy/clippy_lints/src/non_expressive_names.rs b/src/tools/clippy/clippy_lints/src/non_expressive_names.rs
index 45809b35986..2b51b732075 100644
--- a/src/tools/clippy/clippy_lints/src/non_expressive_names.rs
+++ b/src/tools/clippy/clippy_lints/src/non_expressive_names.rs
@@ -1,13 +1,13 @@
 use crate::utils::{span_lint, span_lint_and_then};
 use rustc_ast::ast::{
-    Arm, AssocItem, AssocItemKind, Attribute, Block, FnDecl, Ident, Item, ItemKind, Local, MacCall, Pat, PatKind,
+    Arm, AssocItem, AssocItemKind, Attribute, Block, FnDecl, Item, ItemKind, Local, MacCall, Pat, PatKind,
 };
 use rustc_ast::attr;
 use rustc_ast::visit::{walk_block, walk_expr, walk_pat, Visitor};
 use rustc_lint::{EarlyContext, EarlyLintPass};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::source_map::Span;
-use rustc_span::symbol::SymbolStr;
+use rustc_span::symbol::{Ident, SymbolStr};
 use std::cmp::Ordering;
 
 declare_clippy_lint! {
diff --git a/src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs b/src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs
index 86c469a4dcc..735800e7e74 100644
--- a/src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs
+++ b/src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs
@@ -1,9 +1,9 @@
 use crate::utils::span_lint;
-use rustc_ast::ast::{Ident, Item, ItemKind, UseTree, UseTreeKind};
+use rustc_ast::ast::{Item, ItemKind, UseTree, UseTreeKind};
 use rustc_lint::{EarlyContext, EarlyLintPass};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::source_map::Span;
-use rustc_span::symbol::SymbolStr;
+use rustc_span::symbol::{Ident, SymbolStr};
 
 declare_clippy_lint! {
     /// **What it does:** Checks for imports that remove "unsafe" from an item's
diff --git a/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs b/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs
index 02b721fd378..bd7da57c665 100644
--- a/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs
@@ -1,6 +1,5 @@
 use crate::consts::{constant_context, constant_simple};
 use crate::utils::differing_macro_contexts;
-use rustc_ast::ast::Name;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_hir::{
     BinOpKind, Block, BlockCheckMode, BodyId, BorrowKind, CaptureBy, Expr, ExprKind, Field, FnRetTy, GenericArg,
@@ -10,6 +9,7 @@ use rustc_hir::{
 use rustc_lint::LateContext;
 use rustc_middle::ich::StableHashingContextProvider;
 use rustc_middle::ty::TypeckTables;
+use rustc_span::Symbol;
 use std::hash::Hash;
 
 /// Type used to check whether two ast are the same. This is different from the
@@ -544,7 +544,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
         }
     }
 
-    pub fn hash_name(&mut self, n: Name) {
+    pub fn hash_name(&mut self, n: Symbol) {
         n.as_str().hash(&mut self.s);
     }
 
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs
index 5bf9acdc5f7..8e1b047f6f8 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs
@@ -4,7 +4,7 @@ use crate::utils::{
     span_lint_and_help, span_lint_and_sugg, walk_ptrs_ty,
 };
 use if_chain::if_chain;
-use rustc_ast::ast::{Crate as AstCrate, ItemKind, LitKind, Name, NodeId};
+use rustc_ast::ast::{Crate as AstCrate, ItemKind, LitKind, NodeId};
 use rustc_ast::visit::FnKind;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::Applicability;
@@ -17,7 +17,7 @@ use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};
 use rustc_middle::hir::map::Map;
 use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass};
 use rustc_span::source_map::{Span, Spanned};
-use rustc_span::symbol::SymbolStr;
+use rustc_span::symbol::{Symbol, SymbolStr};
 
 use std::borrow::{Borrow, Cow};
 
@@ -245,8 +245,8 @@ impl EarlyLintPass for ClippyLintsInternal {
 
 #[derive(Clone, Debug, Default)]
 pub struct LintWithoutLintPass {
-    declared_lints: FxHashMap<Name, Span>,
-    registered_lints: FxHashSet<Name>,
+    declared_lints: FxHashMap<Symbol, Span>,
+    registered_lints: FxHashSet<Symbol>,
 }
 
 impl_lint_pass!(LintWithoutLintPass => [DEFAULT_LINT, LINT_WITHOUT_LINT_PASS]);
@@ -357,7 +357,7 @@ fn is_lint_ref_type<'tcx>(cx: &LateContext<'_, 'tcx>, ty: &Ty<'_>) -> bool {
 }
 
 struct LintCollector<'a, 'tcx> {
-    output: &'a mut FxHashSet<Name>,
+    output: &'a mut FxHashSet<Symbol>,
     cx: &'a LateContext<'a, 'tcx>,
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/utils/mod.rs b/src/tools/clippy/clippy_lints/src/utils/mod.rs
index 04b4b423761..2fd080e9ef0 100644
--- a/src/tools/clippy/clippy_lints/src/utils/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/mod.rs
@@ -1069,7 +1069,7 @@ pub fn is_allowed(cx: &LateContext<'_, '_>, lint: &'static Lint, id: HirId) -> b
     cx.tcx.lint_level_at_node(lint, id).0 == Level::Allow
 }
 
-pub fn get_arg_name(pat: &Pat<'_>) -> Option<ast::Name> {
+pub fn get_arg_name(pat: &Pat<'_>) -> Option<Name> {
     match pat.kind {
         PatKind::Binding(.., ident, None) => Some(ident.name),
         PatKind::Ref(ref subpat, _) => get_arg_name(subpat),
diff --git a/src/tools/clippy/clippy_lints/src/utils/ptr.rs b/src/tools/clippy/clippy_lints/src/utils/ptr.rs
index 240bf2449cb..fb6bd5e8158 100644
--- a/src/tools/clippy/clippy_lints/src/utils/ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/ptr.rs
@@ -1,10 +1,9 @@
 use crate::utils::{get_pat_name, match_var, snippet};
-use rustc_ast::ast::Name;
 use rustc_hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
 use rustc_hir::{Body, BodyId, Expr, ExprKind, Param};
 use rustc_lint::LateContext;
 use rustc_middle::hir::map::Map;
-use rustc_span::source_map::Span;
+use rustc_span::{Span, Symbol};
 use std::borrow::Cow;
 
 pub fn get_spans(
@@ -25,7 +24,7 @@ pub fn get_spans(
 
 fn extract_clone_suggestions<'a, 'tcx>(
     cx: &LateContext<'a, 'tcx>,
-    name: Name,
+    name: Symbol,
     replace: &[(&'static str, &'static str)],
     body: &'tcx Body<'_>,
 ) -> Option<Vec<(Span, Cow<'static, str>)>> {
@@ -46,7 +45,7 @@ fn extract_clone_suggestions<'a, 'tcx>(
 
 struct PtrCloneVisitor<'a, 'tcx> {
     cx: &'a LateContext<'a, 'tcx>,
-    name: Name,
+    name: Symbol,
     replace: &'a [(&'static str, &'static str)],
     spans: Vec<(Span, Cow<'static, str>)>,
     abort: bool,
@@ -83,6 +82,6 @@ impl<'a, 'tcx> Visitor<'tcx> for PtrCloneVisitor<'a, 'tcx> {
     }
 }
 
-fn get_binding_name(arg: &Param<'_>) -> Option<Name> {
+fn get_binding_name(arg: &Param<'_>) -> Option<Symbol> {
     get_pat_name(&arg.pat)
 }
diff --git a/src/tools/clippy/clippy_lints/src/utils/usage.rs b/src/tools/clippy/clippy_lints/src/utils/usage.rs
index c14da6aacea..e8535677987 100644
--- a/src/tools/clippy/clippy_lints/src/utils/usage.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/usage.rs
@@ -1,5 +1,4 @@
 use crate::utils::match_var;
-use rustc_ast::ast;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def::Res;
 use rustc_hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
@@ -8,7 +7,7 @@ use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::LateContext;
 use rustc_middle::hir::map::Map;
 use rustc_middle::ty;
-use rustc_span::symbol::Ident;
+use rustc_span::symbol::{Ident, Symbol};
 use rustc_typeck::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, Place, PlaceBase};
 
 /// Returns a set of mutated local variable IDs, or `None` if mutations could not be determined.
@@ -78,7 +77,7 @@ impl<'tcx> Delegate<'tcx> for MutVarsDelegate {
 }
 
 pub struct UsedVisitor {
-    pub var: ast::Name, // var to look for
+    pub var: Symbol,    // var to look for
     pub used: bool,     // has the var been used otherwise?
 }
 
diff --git a/src/tools/clippy/util/dev b/src/tools/clippy/util/dev
new file mode 100755
index 00000000000..319de217e0d
--- /dev/null
+++ b/src/tools/clippy/util/dev
@@ -0,0 +1,7 @@
+#!/bin/sh
+CARGO_TARGET_DIR=$(pwd)/target/
+export CARGO_TARGET_DIR
+
+echo 'Deprecated! `util/dev` usage is deprecated, please use `cargo dev` instead.'
+
+cd clippy_dev && cargo run -- "$@"
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 1423f1db385..d3c7b7a068b 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -80,6 +80,10 @@ const WHITELIST: &[&str] = &[
     "c2-chacha",
     "cc",
     "cfg-if",
+    "chalk-derive",
+    "chalk-engine",
+    "chalk-ir",
+    "chalk-macros",
     "cloudabi",
     "cmake",
     "compiler_builtins",