about summary refs log tree commit diff
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2020-03-30 12:36:28 -0700
committerGitHub <noreply@github.com>2020-03-30 12:36:28 -0700
commit5ca3d023ff6c970e7dcd6cee3c83672dff14dc15 (patch)
tree2cc8d28e47d2d970c06829e3a5eb01ed48bde0ea
parent9f53665f91be16c9aa7afd83f7c79357fec9152b (diff)
parent9714a140c99a8968b0becb5cf9227b1787768088 (diff)
Merge pull request #4100 from calebcartwright/rustfmt1x-rustc-v650
bump rustfmt 1x to rustc-ap v651
-rw-r--r--Cargo.lock287
-rw-r--r--Cargo.toml30
-rw-r--r--src/attr.rs13
-rw-r--r--src/chains.rs14
-rw-r--r--src/closures.rs14
-rw-r--r--src/comment.rs4
-rw-r--r--src/expr.rs41
-rw-r--r--src/formatting.rs465
-rw-r--r--src/imports.rs2
-rw-r--r--src/items.rs125
-rw-r--r--src/lib.rs13
-rw-r--r--src/lists.rs4
-rw-r--r--src/macros.rs35
-rw-r--r--src/matches.rs11
-rw-r--r--src/missed_spans.rs25
-rw-r--r--src/modules.rs286
-rw-r--r--src/modules/visitor.rs75
-rw-r--r--src/overflow.rs4
-rw-r--r--src/pairs.rs2
-rw-r--r--src/patterns.rs10
-rw-r--r--src/reorder.rs6
-rw-r--r--src/rewrite.rs11
-rw-r--r--src/skip.rs4
-rw-r--r--src/source_file.rs17
-rw-r--r--src/source_map.rs29
-rw-r--r--src/spanned.rs11
-rw-r--r--src/stmt.rs4
-rw-r--r--src/syntux.rs4
-rw-r--r--src/syntux/parser.rs312
-rw-r--r--src/syntux/session.rs441
-rw-r--r--src/types.rs26
-rw-r--r--src/utils.rs38
-rw-r--r--src/vertical.rs2
-rw-r--r--src/visitor.rs148
-rw-r--r--tests/source/imports.rs16
-rw-r--r--tests/source/issue_4057.rs15
-rw-r--r--tests/target/imports.rs10
-rw-r--r--tests/target/issue-4068.rs3
-rw-r--r--tests/target/issue_4057.rs15
39 files changed, 1455 insertions, 1117 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 094fcfd384b..d8b087503d8 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -495,6 +495,15 @@ dependencies = [
 ]
 
 [[package]]
+name = "parking_lot"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "lock_api 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "parking_lot_core"
 version = "0.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -509,6 +518,19 @@ dependencies = [
 ]
 
 [[package]]
+name = "parking_lot_core"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "proc-macro-error"
 version = "0.2.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -617,64 +639,97 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-arena"
-version = "642.0.0"
+version = "651.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "rustc-ap-rustc_data_structures 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-graphviz"
-version = "642.0.0"
+version = "651.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
+name = "rustc-ap-rustc_ast"
+version = "651.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_index 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_lexer 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_macros 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_span 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rustc-ap-rustc_ast_passes"
+version = "651.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_ast 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_ast_pretty 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_attr 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_errors 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_feature 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_parse 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_session 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_span 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "rustc-ap-rustc_ast_pretty"
-version = "642.0.0"
+version = "651.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_data_structures 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_span 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_ast 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_span 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-rustc_attr"
-version = "642.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "rustc-ap-rustc_ast_pretty 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_data_structures 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_errors 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_feature 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_macros 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_session 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_span 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+version = "651.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rustc-ap-rustc_ast 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_ast_pretty 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_errors 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_feature 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_macros 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_session 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_span 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-rustc_data_structures"
-version = "642.0.0"
+version = "651.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "ena 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "jobserver 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "measureme 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-graphviz 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_index 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-graphviz 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_index 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-rayon 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-rayon-core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -685,15 +740,15 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-rustc_errors"
-version = "642.0.0"
+version = "651.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "annotate-snippets 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_data_structures 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_span 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_span 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "termize 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -701,32 +756,53 @@ dependencies = [
 ]
 
 [[package]]
+name = "rustc-ap-rustc_expand"
+version = "651.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_ast 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_ast_passes 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_ast_pretty 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_attr 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_errors 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_feature 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_lexer 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_parse 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_session 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_span 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "rustc-ap-rustc_feature"
-version = "642.0.0"
+version = "651.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_data_structures 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_span 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_span 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-rustc_fs_util"
-version = "642.0.0"
+version = "651.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "rustc-ap-rustc_index"
-version = "642.0.0"
+version = "651.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "rustc-ap-serialize 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-rustc_lexer"
-version = "642.0.0"
+version = "651.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -734,10 +810,9 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-rustc_macros"
-version = "642.0.0"
+version = "651.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -746,75 +821,74 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-rustc_parse"
-version = "642.0.0"
+version = "651.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_ast_pretty 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_attr 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_data_structures 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_errors 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_feature 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_lexer 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_session 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_span 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_ast 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_ast_pretty 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_errors 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_feature 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_lexer 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_session 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_span 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-normalization 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-rustc_session"
-version = "642.0.0"
+version = "651.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_data_structures 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_errors 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_feature 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_fs_util 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_index 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_span 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_target 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_ast 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_errors 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_feature 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_fs_util 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_index 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_span 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_target 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-rustc_span"
-version = "642.0.0"
+version = "651.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-arena 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_data_structures 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_index 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_macros 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-arena 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_index 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_macros 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-rustc_target"
-version = "642.0.0"
+version = "651.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_data_structures 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_index 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_macros 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_span 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_index 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_macros 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_span 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-serialize"
-version = "642.0.0"
+version = "651.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -822,22 +896,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "rustc-ap-syntax"
-version = "642.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_data_structures 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_index 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_lexer 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_macros 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_span 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
 name = "rustc-demangle"
 version = "0.1.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -912,14 +970,15 @@ dependencies = [
  "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_ast_pretty 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_data_structures 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_errors 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_parse 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_session 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_span 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_target 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_ast 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_ast_pretty 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_errors 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_expand 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_parse 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_session 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_span 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_target 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-workspace-hack 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustfmt-config_proc_macro 0.2.0",
  "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1261,8 +1320,10 @@ dependencies = [
 "checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
 "checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273"
 "checksum packed_simd 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a85ea9fc0d4ac0deb6fe7911d38786b32fc11119afd9e9d38b84ff691ce64220"
+"checksum parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc"
 "checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252"
 "checksum parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b"
+"checksum parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7582838484df45743c8434fbff785e8edf260c28748353d44bc0da32e0ceabf1"
 "checksum proc-macro-error 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "aeccfe4d5d8ea175d5f0e4a2ad0637e0f4121d63bd99d356fb1f39ab2e7c6097"
 "checksum proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27"
 "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
@@ -1276,23 +1337,25 @@ dependencies = [
 "checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd"
 "checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716"
 "checksum rust-argon2 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ca4eaef519b494d1f2848fc602d18816fed808a981aedf4f1f00ceb7c9d32cf"
-"checksum rustc-ap-arena 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea82fa3d9a8add7422228ca1a2cbba0784fa8861f56148ff64da08b3c7921b03"
-"checksum rustc-ap-graphviz 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "638d0b2b3bcf99824e0cb5a25dbc547b61dc20942e11daf6a97e981918aa18e5"
-"checksum rustc-ap-rustc_ast_pretty 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d38bab04dd676dee6d2f9670506a18c31bfce38bf7f8420aa83eb1140ecde049"
-"checksum rustc-ap-rustc_attr 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "10b843ba8b1ed43739133047673b9f6a54d3b3b4d328d69c6ea89ff971395f35"
-"checksum rustc-ap-rustc_data_structures 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dc3d1c6d0a80ab0c1df76405377cec0f3d5423fb5b0953a8eac70a2ad6c44df2"
-"checksum rustc-ap-rustc_errors 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4909a1eca29331332257230f29120a8ff68c9e37d868c564fcd599e430cf8914"
-"checksum rustc-ap-rustc_feature 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "63ab887a181d795cf5fd3edadf367760deafb90aefb844f168ab5255266e3478"
-"checksum rustc-ap-rustc_fs_util 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "70814116df3c5fbec8f06f6a1d013ca481f620fd22a9475754e9bf3ee9ba70d8"
-"checksum rustc-ap-rustc_index 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac1bf1d3cf3d119d41353d6fd229ef7272d5097bc0924de021c0294bf86d48bf"
-"checksum rustc-ap-rustc_lexer 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4cda21a32cebdc11ec4f5393aa2fcde5ed1b2f673a8571e5a4dcdf07e4ae9cac"
-"checksum rustc-ap-rustc_macros 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75c47b48ea51910ecfd853c9248a9bf4c767bc823449ab6a1d864dff65fbae16"
-"checksum rustc-ap-rustc_parse 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "abd88e89cd5b5d28dcd3a347a3d534c08627d9455570dc1a2d402cb8437b9d30"
-"checksum rustc-ap-rustc_session 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8487b4575fbb2d1fc6f1cd61225efd108a4d36817e6fb9b643d57fcae9cb12"
-"checksum rustc-ap-rustc_span 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f69746c0d4c21bf20a5bb2bd247261a1aa8631f04202d7303352942dde70d987"
-"checksum rustc-ap-rustc_target 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8bbc6ae09b5d42ec66edd520e8412e0615c53a7c93607fe33dc4abab60ba7c8b"
-"checksum rustc-ap-serialize 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e13a1ead0252fc3d96da4c336a95950be6795f2b00c84a67ccadf26142f8cb41"
-"checksum rustc-ap-syntax 642.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e1f59f48ca3a2ec16a7e82e718ed5aadf9c9e08cf63015d28b4e774767524a6a"
+"checksum rustc-ap-arena 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "632704fb93ca8148957191e5d2d827082f93c4aa20cdd242fb46d8cca57029da"
+"checksum rustc-ap-graphviz 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bdd4689b814859c9f1b3e314ed2bde596acac428a256a16894635f600bed46b4"
+"checksum rustc-ap-rustc_ast 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "101c1517d3fd19d083aaca5b113f9965e6ae353a0bb09c49959b0f62b95b75d9"
+"checksum rustc-ap-rustc_ast_passes 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ab3f5a7e939b37c99d8ca371f09b10bb5b5c85ad5d5b8d1d736ce8248c71be0"
+"checksum rustc-ap-rustc_ast_pretty 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05046d3a2b8de22b20bcda9a1c063dc5c1f2f721f042b6c2809df2d23c64a13e"
+"checksum rustc-ap-rustc_attr 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f00b7ccad6fc3628fb44950435772945a425575f9ea0b3708c536fe75623a6e8"
+"checksum rustc-ap-rustc_data_structures 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4c6121ab6766644fa76b711f65d4c39f2e335488ab768324567fed0ed191166e"
+"checksum rustc-ap-rustc_errors 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "adab84c842003ad1c8435fd71b8d0cc19bf0d702a8a2147d5be06e083db2d207"
+"checksum rustc-ap-rustc_expand 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb001df541ea02b65c8e294252530010c6f90e3c6a5716e8e24e58c12dd1cd86"
+"checksum rustc-ap-rustc_feature 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "446cc60613cc3b05d0bdbcab7feb02305790b5617fa43c532d51ae3223d677a4"
+"checksum rustc-ap-rustc_fs_util 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9ac99d6f67e7db3bb300895630e769ed41bd3e336c0e725870c70e676c1a5ff1"
+"checksum rustc-ap-rustc_index 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5608c1cf50d2251b7e10a138cf6dd388e97f139b21c00b06a22d06f89c6591f6"
+"checksum rustc-ap-rustc_lexer 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74e9c1c6f5dc85977b3adb6fb556b2ff23354d1a12021da15eb1d36353458bde"
+"checksum rustc-ap-rustc_macros 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3226b5ec864312a5d23eb40a5d621ee06bdc0754228d20d6eb76d4ddc4f2d4a1"
+"checksum rustc-ap-rustc_parse 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba3b042344c2280b50d5df0058d11379028a8f016a407e575bb3ea8b6c798049"
+"checksum rustc-ap-rustc_session 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff35ef4b5d9fbcb2fd539c7c908eb3cdd1f68ddbccd042945ef50ae65564f941"
+"checksum rustc-ap-rustc_span 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e323b1f4a824039886eed8e33cad20ea4f492a9f9b3c9441009797c91de3e87a"
+"checksum rustc-ap-rustc_target 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e161eb7b3a5b7993c6b480135296dc61476db80041d49dd446422742426e390b"
+"checksum rustc-ap-serialize 651.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "af510a659098d8c45a7303fb882fa780f4a87ec5f5d7a2053521e7d5d7f332c4"
 "checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
 "checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8"
 "checksum rustc-rayon 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f32767f90d938f1b7199a174ef249ae1924f6e5bbdb9d112fea141e016f25b3a"
diff --git a/Cargo.toml b/Cargo.toml
index 1cfa80de8bd..de934e60b8f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -56,43 +56,45 @@ ignore = "0.4.11"
 annotate-snippets = { version = "0.6", features = ["ansi_term"] }
 structopt = "0.3"
 rustfmt-config_proc_macro = { version = "0.2", path = "config_proc_macro" }
+lazy_static = "1.0.0"
 
 # A noop dependency that changes in the Rust repository, it's a bit of a hack.
 # See the `src/tools/rustc-workspace-hack/README.md` file in `rust-lang/rust`
 # for more information.
 rustc-workspace-hack = "1.0.0"
 
+[dependencies.rustc_ast]
+package = "rustc-ap-rustc_ast"
+version = "651.0.0"
+
 [dependencies.rustc_ast_pretty]
 package = "rustc-ap-rustc_ast_pretty"
-version = "642.0.0"
+version = "651.0.0"
 
 [dependencies.rustc_data_structures]
 package = "rustc-ap-rustc_data_structures"
-version = "642.0.0"
+version = "651.0.0"
 
 [dependencies.rustc_errors]
 package = "rustc-ap-rustc_errors"
-version = "642.0.0"
+version = "651.0.0"
+
+[dependencies.rustc_expand]
+package = "rustc-ap-rustc_expand"
+version = "651.0.0"
 
 [dependencies.rustc_parse]
 package = "rustc-ap-rustc_parse"
-version = "642.0.0"
+version = "651.0.0"
 
 [dependencies.rustc_session]
 package = "rustc-ap-rustc_session"
-version = "642.0.0"
+version = "651.0.0"
 
 [dependencies.rustc_span]
 package = "rustc-ap-rustc_span"
-version = "642.0.0"
+version = "651.0.0"
 
 [dependencies.rustc_target]
 package = "rustc-ap-rustc_target"
-version = "642.0.0"
-
-[dependencies.syntax]
-package = "rustc-ap-syntax"
-version = "642.0.0"
-
-[dev-dependencies]
-lazy_static = "1.0.0"
+version = "651.0.0"
diff --git a/src/attr.rs b/src/attr.rs
index 461f0ddf029..b9e160020fb 100644
--- a/src/attr.rs
+++ b/src/attr.rs
@@ -1,7 +1,8 @@
 //! Format attributes and meta items.
 
+use rustc_ast::ast;
+use rustc_ast::attr::HasAttrs;
 use rustc_span::{symbol::sym, BytePos, Span, DUMMY_SP};
-use syntax::ast;
 
 use self::doc_comment::DocCommentFormatter;
 use crate::comment::{contains_comment, rewrite_doc_comment, CommentStyle};
@@ -19,12 +20,7 @@ mod doc_comment;
 
 /// Returns attributes on the given statement.
 pub(crate) fn get_attrs_from_stmt(stmt: &ast::Stmt) -> &[ast::Attribute] {
-    match stmt.kind {
-        ast::StmtKind::Local(ref local) => &local.attrs,
-        ast::StmtKind::Item(ref item) => &item.attrs,
-        ast::StmtKind::Expr(ref expr) | ast::StmtKind::Semi(ref expr) => &expr.attrs,
-        ast::StmtKind::Mac(ref mac) => &mac.2,
-    }
+    stmt.attrs()
 }
 
 pub(crate) fn get_span_without_attrs(stmt: &ast::Stmt) -> Span {
@@ -32,10 +28,11 @@ pub(crate) fn get_span_without_attrs(stmt: &ast::Stmt) -> Span {
         ast::StmtKind::Local(ref local) => local.span,
         ast::StmtKind::Item(ref item) => item.span,
         ast::StmtKind::Expr(ref expr) | ast::StmtKind::Semi(ref expr) => expr.span,
-        ast::StmtKind::Mac(ref mac) => {
+        ast::StmtKind::MacCall(ref mac) => {
             let (ref mac, _, _) = **mac;
             mac.span()
         }
+        ast::StmtKind::Empty => stmt.span,
     }
 }
 
diff --git a/src/chains.rs b/src/chains.rs
index a7a9127cbbd..40e4d483993 100644
--- a/src/chains.rs
+++ b/src/chains.rs
@@ -58,8 +58,8 @@
 use std::borrow::Cow;
 use std::cmp::min;
 
+use rustc_ast::{ast, ptr};
 use rustc_span::{BytePos, Span};
-use syntax::{ast, ptr};
 
 use crate::comment::{rewrite_comment, CharClasses, FullCodeCharKind, RichChar};
 use crate::config::IndentStyle;
@@ -148,7 +148,15 @@ impl ChainItemKind {
             ast::ExprKind::MethodCall(ref segment, ref expressions) => {
                 let types = if let Some(ref generic_args) = segment.args {
                     if let ast::GenericArgs::AngleBracketed(ref data) = **generic_args {
-                        data.args.clone()
+                        data.args
+                            .iter()
+                            .filter_map(|x| match x {
+                                ast::AngleBracketedArg::Arg(ref generic_arg) => {
+                                    Some(generic_arg.clone())
+                                }
+                                _ => None,
+                            })
+                            .collect::<Vec<_>>()
                     } else {
                         vec![]
                     }
@@ -403,7 +411,7 @@ impl Chain {
 
     fn convert_try(expr: &ast::Expr, context: &RewriteContext<'_>) -> ast::Expr {
         match expr.kind {
-            ast::ExprKind::Mac(ref mac) if context.config.use_try_shorthand() => {
+            ast::ExprKind::MacCall(ref mac) if context.config.use_try_shorthand() => {
                 if let Some(subexpr) = convert_try_mac(mac, context) {
                     subexpr
                 } else {
diff --git a/src/closures.rs b/src/closures.rs
index 18e867cabd1..82c49d806b5 100644
--- a/src/closures.rs
+++ b/src/closures.rs
@@ -1,5 +1,5 @@
+use rustc_ast::{ast, ptr};
 use rustc_span::Span;
-use syntax::{ast, ptr};
 
 use crate::attr::get_attrs_from_stmt;
 use crate::config::lists::*;
@@ -25,7 +25,7 @@ use crate::utils::{last_line_width, left_most_sub_expr, stmt_expr, NodeIdExt};
 
 pub(crate) fn rewrite_closure(
     capture: ast::CaptureBy,
-    is_async: &ast::IsAsync,
+    is_async: &ast::Async,
     movability: ast::Movability,
     fn_decl: &ast::FnDecl,
     body: &ast::Expr,
@@ -43,14 +43,14 @@ pub(crate) fn rewrite_closure(
 
     if let ast::ExprKind::Block(ref block, _) = body.kind {
         // The body of the closure is an empty block.
-        if block.stmts.is_empty() && !block_contains_comment(block, context.source_map) {
+        if block.stmts.is_empty() && !block_contains_comment(context, block) {
             return body
                 .rewrite(context, shape)
                 .map(|s| format!("{} {}", prefix, s));
         }
 
         let result = match fn_decl.output {
-            ast::FunctionRetTy::Default(_) if !context.inside_macro() => {
+            ast::FnRetTy::Default(_) if !context.inside_macro() => {
                 try_rewrite_without_block(body, &prefix, context, shape, body_shape)
             }
             _ => None,
@@ -112,7 +112,7 @@ fn needs_block(block: &ast::Block, prefix: &str, context: &RewriteContext<'_>) -
     is_unsafe_block(block)
         || block.stmts.len() > 1
         || has_attributes
-        || block_contains_comment(block, context.source_map)
+        || block_contains_comment(context, block)
         || prefix.contains('\n')
 }
 
@@ -214,7 +214,7 @@ fn rewrite_closure_block(
 // Return type is (prefix, extra_offset)
 fn rewrite_closure_fn_decl(
     capture: ast::CaptureBy,
-    asyncness: &ast::IsAsync,
+    asyncness: &ast::Async,
     movability: ast::Movability,
     fn_decl: &ast::FnDecl,
     body: &ast::Expr,
@@ -305,7 +305,7 @@ pub(crate) fn rewrite_last_closure(
             ast::ExprKind::Block(ref block, _)
                 if !is_unsafe_block(block)
                     && !context.inside_macro()
-                    && is_simple_block(block, Some(&body.attrs), context.source_map) =>
+                    && is_simple_block(context, block, Some(&body.attrs)) =>
             {
                 stmt_expr(&block.stmts[0]).unwrap_or(body)
             }
diff --git a/src/comment.rs b/src/comment.rs
index 5b46001ff7d..518f2bcda0c 100644
--- a/src/comment.rs
+++ b/src/comment.rs
@@ -1556,10 +1556,10 @@ pub(crate) fn recover_comment_removed(
         // We missed some comments. Warn and keep the original text.
         if context.config.error_on_unformatted() {
             context.report.append(
-                context.source_map.span_to_filename(span).into(),
+                context.parse_sess.span_to_filename(span),
                 vec![FormattingError::from_span(
                     span,
-                    &context.source_map,
+                    &context.parse_sess,
                     ErrorKind::LostComment,
                 )],
             );
diff --git a/src/expr.rs b/src/expr.rs
index 84f01f2a1a9..8545b0f6f29 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -2,9 +2,9 @@ use std::borrow::Cow;
 use std::cmp::min;
 
 use itertools::Itertools;
-use rustc_span::{source_map::SourceMap, BytePos, Span};
-use syntax::token::{DelimToken, LitKind};
-use syntax::{ast, ptr};
+use rustc_ast::token::{DelimToken, LitKind};
+use rustc_ast::{ast, ptr};
+use rustc_span::{BytePos, Span};
 
 use crate::chains::rewrite_chain;
 use crate::closures;
@@ -199,7 +199,7 @@ pub(crate) fn format_expr(
         ast::ExprKind::Try(..) | ast::ExprKind::Field(..) | ast::ExprKind::MethodCall(..) => {
             rewrite_chain(expr, context, shape)
         }
-        ast::ExprKind::Mac(ref mac) => {
+        ast::ExprKind::MacCall(ref mac) => {
             rewrite_macro(mac, None, context, shape, MacroPosition::Expression).or_else(|| {
                 wrap_str(
                     context.snippet(expr.span).to_owned(),
@@ -322,7 +322,7 @@ pub(crate) fn format_expr(
         }
         // We do not format these expressions yet, but they should still
         // satisfy our width restrictions.
-        ast::ExprKind::InlineAsm(..) => Some(context.snippet(expr.span).to_owned()),
+        ast::ExprKind::LlvmInlineAsm(..) => Some(context.snippet(expr.span).to_owned()),
         ast::ExprKind::TryBlock(ref block) => {
             if let rw @ Some(_) =
                 rewrite_single_line_block(context, "try ", block, Some(&expr.attrs), None, shape)
@@ -430,7 +430,7 @@ fn rewrite_empty_block(
         return None;
     }
 
-    if !block_contains_comment(block, context.source_map) && shape.width >= 2 {
+    if !block_contains_comment(context, block) && shape.width >= 2 {
         return Some(format!("{}{}{{}}", prefix, label_str));
     }
 
@@ -487,7 +487,7 @@ fn rewrite_single_line_block(
     label: Option<ast::Label>,
     shape: Shape,
 ) -> Option<String> {
-    if is_simple_block(block, attrs, context.source_map) {
+    if is_simple_block(context, block, attrs) {
         let expr_shape = shape.offset_left(last_line_width(prefix))?;
         let expr_str = block.stmts[0].rewrite(context, expr_shape)?;
         let label_str = rewrite_label(label);
@@ -750,8 +750,8 @@ impl<'a> ControlFlow<'a> {
         let fixed_cost = self.keyword.len() + "  {  } else {  }".len();
 
         if let ast::ExprKind::Block(ref else_node, _) = else_block.kind {
-            if !is_simple_block(self.block, None, context.source_map)
-                || !is_simple_block(else_node, None, context.source_map)
+            if !is_simple_block(context, self.block, None)
+                || !is_simple_block(context, else_node, None)
                 || pat_expr_str.contains('\n')
             {
                 return None;
@@ -1134,9 +1134,8 @@ fn extract_comment(span: Span, context: &RewriteContext<'_>, shape: Shape) -> Op
     }
 }
 
-pub(crate) fn block_contains_comment(block: &ast::Block, source_map: &SourceMap) -> bool {
-    let snippet = source_map.span_to_snippet(block.span).unwrap();
-    contains_comment(&snippet)
+pub(crate) fn block_contains_comment(context: &RewriteContext<'_>, block: &ast::Block) -> bool {
+    contains_comment(context.snippet(block.span))
 }
 
 // Checks that a block contains no statements, an expression and no comments or
@@ -1144,37 +1143,37 @@ pub(crate) fn block_contains_comment(block: &ast::Block, source_map: &SourceMap)
 // FIXME: incorrectly returns false when comment is contained completely within
 // the expression.
 pub(crate) fn is_simple_block(
+    context: &RewriteContext<'_>,
     block: &ast::Block,
     attrs: Option<&[ast::Attribute]>,
-    source_map: &SourceMap,
 ) -> bool {
     block.stmts.len() == 1
         && stmt_is_expr(&block.stmts[0])
-        && !block_contains_comment(block, source_map)
+        && !block_contains_comment(context, block)
         && attrs.map_or(true, |a| a.is_empty())
 }
 
 /// Checks whether a block contains at most one statement or expression, and no
 /// comments or attributes.
 pub(crate) fn is_simple_block_stmt(
+    context: &RewriteContext<'_>,
     block: &ast::Block,
     attrs: Option<&[ast::Attribute]>,
-    source_map: &SourceMap,
 ) -> bool {
     block.stmts.len() <= 1
-        && !block_contains_comment(block, source_map)
+        && !block_contains_comment(context, block)
         && attrs.map_or(true, |a| a.is_empty())
 }
 
 /// Checks whether a block contains no statements, expressions, comments, or
 /// inner attributes.
 pub(crate) fn is_empty_block(
+    context: &RewriteContext<'_>,
     block: &ast::Block,
     attrs: Option<&[ast::Attribute]>,
-    source_map: &SourceMap,
 ) -> bool {
     block.stmts.is_empty()
-        && !block_contains_comment(block, source_map)
+        && !block_contains_comment(context, block)
         && attrs.map_or(true, |a| inner_attributes(a).is_empty())
 }
 
@@ -1313,9 +1312,9 @@ pub(crate) fn can_be_overflowed_expr(
             context.config.overflow_delimited_expr()
                 || (context.use_block_indent() && args_len == 1)
         }
-        ast::ExprKind::Mac(ref mac) => {
+        ast::ExprKind::MacCall(ref mac) => {
             match (
-                syntax::ast::MacDelimiter::from_token(mac.args.delim()),
+                rustc_ast::ast::MacDelimiter::from_token(mac.args.delim()),
                 context.config.overflow_delimited_expr(),
             ) {
                 (Some(ast::MacDelimiter::Bracket), true)
@@ -1341,7 +1340,7 @@ pub(crate) fn can_be_overflowed_expr(
 
 pub(crate) fn is_nested_call(expr: &ast::Expr) -> bool {
     match expr.kind {
-        ast::ExprKind::Call(..) | ast::ExprKind::Mac(..) => true,
+        ast::ExprKind::Call(..) | ast::ExprKind::MacCall(..) => true,
         ast::ExprKind::AddrOf(_, _, ref expr)
         | ast::ExprKind::Box(ref expr)
         | ast::ExprKind::Try(ref expr)
diff --git a/src/formatting.rs b/src/formatting.rs
index bed87748253..8178342f28c 100644
--- a/src/formatting.rs
+++ b/src/formatting.rs
@@ -1,29 +1,20 @@
 // High level formatting functions.
 
-use std::cell::RefCell;
 use std::collections::HashMap;
 use std::io::{self, Write};
-use std::panic::{catch_unwind, AssertUnwindSafe};
-use std::rc::Rc;
 use std::time::{Duration, Instant};
 
-use rustc_data_structures::sync::{Lrc, Send};
-use rustc_errors::emitter::{Emitter, EmitterWriter};
-use rustc_errors::{ColorConfig, Diagnostic, DiagnosticBuilder, Handler, Level as DiagnosticLevel};
-use rustc_session::parse::ParseSess;
-use rustc_span::{
-    source_map::{FilePathMapping, SourceMap},
-    Span, DUMMY_SP,
-};
-use syntax::ast;
+use rustc_ast::ast;
+use rustc_span::Span;
 
 use self::newline_style::apply_newline_style;
 use crate::comment::{CharClasses, FullCodeCharKind};
 use crate::config::{Config, FileName, Verbosity};
-use crate::ignore_path::IgnorePathSet;
 use crate::issues::BadIssueSeeker;
+use crate::syntux::parser::{DirectoryOwnership, Parser, ParserError};
+use crate::syntux::session::ParseSess;
 use crate::utils::count_newlines;
-use crate::visitor::{FmtVisitor, SnippetProvider};
+use crate::visitor::FmtVisitor;
 use crate::{modules, source_file, ErrorKind, FormatReport, Input, Session};
 
 mod newline_style;
@@ -38,7 +29,7 @@ impl<'b, T: Write + 'b> Session<'b, T> {
             return Err(ErrorKind::VersionMismatch);
         }
 
-        syntax::with_globals(self.config.edition().to_libsyntax_pos_edition(), || {
+        rustc_ast::with_globals(self.config.edition().to_libsyntax_pos_edition(), || {
             if self.config.disable_all_formatting() {
                 // When the input is from stdin, echo back the input.
                 if let Input::Text(ref buf) = input {
@@ -71,54 +62,42 @@ fn format_project<T: FormatHandler>(
     let main_file = input.file_name();
     let input_is_stdin = main_file == FileName::Stdin;
 
-    let ignore_path_set = match IgnorePathSet::from_ignore_list(&config.ignore()) {
-        Ok(set) => Rc::new(set),
-        Err(e) => return Err(ErrorKind::InvalidGlobPattern(e)),
-    };
-    if config.skip_children() && ignore_path_set.is_match(&main_file) {
+    let mut parse_session = ParseSess::new(config)?;
+    if config.skip_children() && parse_session.ignore_file(&main_file) {
         return Ok(FormatReport::new());
     }
 
     // Parse the crate.
-    let can_reset_parser_errors = Rc::new(RefCell::new(false));
-    let source_map = Rc::new(SourceMap::new(FilePathMapping::empty()));
-    let mut parse_session = make_parse_sess(
-        source_map.clone(),
-        config,
-        Rc::clone(&ignore_path_set),
-        can_reset_parser_errors.clone(),
-    );
     let mut report = FormatReport::new();
     let directory_ownership = input.to_directory_ownership();
-    let krate = match parse_crate(
-        input,
-        &parse_session,
-        config,
-        &mut report,
-        directory_ownership,
-        can_reset_parser_errors.clone(),
-    ) {
+    let krate = match Parser::parse_crate(config, input, directory_ownership, &parse_session) {
         Ok(krate) => krate,
         // Surface parse error via Session (errors are merged there from report)
-        Err(ErrorKind::ParseError) => return Ok(report),
-        Err(e) => return Err(e),
+        Err(e) => {
+            let forbid_verbose = input_is_stdin || e != ParserError::ParsePanicError;
+            should_emit_verbose(forbid_verbose, config, || {
+                eprintln!("The Rust parser panicked");
+            });
+            report.add_parsing_error();
+            return Ok(report);
+        }
     };
     timer = timer.done_parsing();
 
     // Suppress error output if we have to do any further parsing.
-    let silent_emitter = silent_emitter();
-    parse_session.span_diagnostic = Handler::with_emitter(true, None, silent_emitter);
+    parse_session.set_silent_emitter();
 
     let mut context = FormatContext::new(&krate, report, parse_session, config, handler);
     let files = modules::ModResolver::new(
         &context.parse_session,
-        directory_ownership.unwrap_or(rustc_parse::DirectoryOwnership::UnownedViaMod),
-        !(input_is_stdin || config.skip_children()),
+        directory_ownership.unwrap_or(DirectoryOwnership::UnownedViaMod),
+        !input_is_stdin && !config.skip_children(),
     )
     .visit_crate(&krate)
     .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
+
     for (path, module) in files {
-        let should_ignore = !input_is_stdin && ignore_path_set.is_match(&path);
+        let should_ignore = !input_is_stdin && context.ignore_file(&path);
         if (config.skip_children() && path != main_file) || should_ignore {
             continue;
         }
@@ -150,6 +129,10 @@ struct FormatContext<'a, T: FormatHandler> {
 }
 
 impl<'a, T: FormatHandler + 'a> FormatContext<'a, T> {
+    fn ignore_file(&self, path: &FileName) -> bool {
+        self.parse_session.ignore_file(path)
+    }
+
     // Formats a single file/module.
     fn format_file(
         &mut self,
@@ -157,15 +140,8 @@ impl<'a, T: FormatHandler + 'a> FormatContext<'a, T> {
         module: &ast::Mod,
         is_root: bool,
     ) -> Result<(), ErrorKind> {
-        let source_file = self
-            .parse_session
-            .source_map()
-            .lookup_char_pos(module.inner.lo())
-            .file;
-        let big_snippet = source_file.src.as_ref().unwrap();
-        let snippet_provider =
-            SnippetProvider::new(source_file.start_pos, source_file.end_pos, big_snippet);
-        let mut visitor = FmtVisitor::from_source_map(
+        let snippet_provider = self.parse_session.snippet_provider(module.inner);
+        let mut visitor = FmtVisitor::from_parse_sess(
             &self.parse_session,
             &self.config,
             &snippet_provider,
@@ -175,16 +151,16 @@ impl<'a, T: FormatHandler + 'a> FormatContext<'a, T> {
 
         // Format inner attributes if available.
         if !self.krate.attrs.is_empty() && is_root {
-            visitor.skip_empty_lines(source_file.end_pos);
+            visitor.skip_empty_lines(snippet_provider.end_pos());
             if visitor.visit_attrs(&self.krate.attrs, ast::AttrStyle::Inner) {
                 visitor.push_rewrite(module.inner, None);
             } else {
-                visitor.format_separate_mod(module, &*source_file);
+                visitor.format_separate_mod(module, snippet_provider.end_pos());
             }
         } else {
-            visitor.last_pos = source_file.start_pos;
-            visitor.skip_empty_lines(source_file.end_pos);
-            visitor.format_separate_mod(module, &*source_file);
+            visitor.last_pos = snippet_provider.start_pos();
+            visitor.skip_empty_lines(snippet_provider.end_pos());
+            visitor.format_separate_mod(module, snippet_provider.end_pos());
         };
 
         debug_assert_eq!(
@@ -209,7 +185,7 @@ impl<'a, T: FormatHandler + 'a> FormatContext<'a, T> {
         apply_newline_style(
             self.config.newline_style(),
             &mut visitor.buffer,
-            &big_snippet,
+            snippet_provider.entire_snippet(),
         );
 
         if visitor.macro_rewrite_failure {
@@ -219,7 +195,7 @@ impl<'a, T: FormatHandler + 'a> FormatContext<'a, T> {
             .add_non_formatted_ranges(visitor.skipped_range.borrow().clone());
 
         self.handler.handle_formatted_file(
-            self.parse_session.source_map(),
+            &self.parse_session,
             path,
             visitor.buffer.to_owned(),
             &mut self.report,
@@ -231,7 +207,7 @@ impl<'a, T: FormatHandler + 'a> FormatContext<'a, T> {
 trait FormatHandler {
     fn handle_formatted_file(
         &mut self,
-        source_map: &SourceMap,
+        parse_session: &ParseSess,
         path: FileName,
         result: String,
         report: &mut FormatReport,
@@ -242,14 +218,14 @@ impl<'b, T: Write + 'b> FormatHandler for Session<'b, T> {
     // Called for each formatted file.
     fn handle_formatted_file(
         &mut self,
-        source_map: &SourceMap,
+        parse_session: &ParseSess,
         path: FileName,
         result: String,
         report: &mut FormatReport,
     ) -> Result<(), ErrorKind> {
         if let Some(ref mut out) = self.out {
             match source_file::write_file(
-                Some(source_map),
+                Some(parse_session),
                 &path,
                 &result,
                 out,
@@ -282,23 +258,15 @@ pub(crate) struct FormattingError {
 impl FormattingError {
     pub(crate) fn from_span(
         span: Span,
-        source_map: &SourceMap,
+        parse_sess: &ParseSess,
         kind: ErrorKind,
     ) -> FormattingError {
         FormattingError {
-            line: source_map.lookup_char_pos(span.lo()).line,
+            line: parse_sess.line_of_byte_pos(span.lo()),
             is_comment: kind.is_comment(),
             kind,
             is_string: false,
-            line_buffer: source_map
-                .span_to_lines(span)
-                .ok()
-                .and_then(|fl| {
-                    fl.file
-                        .get_line(fl.lines[0].line_index)
-                        .map(std::borrow::Cow::into_owned)
-                })
-                .unwrap_or_else(String::new),
+            line_buffer: parse_sess.span_to_first_line_string(span),
         }
     }
 
@@ -633,358 +601,11 @@ impl<'a> FormatLines<'a> {
     }
 }
 
-fn parse_crate(
-    input: Input,
-    parse_session: &ParseSess,
-    config: &Config,
-    report: &mut FormatReport,
-    directory_ownership: Option<rustc_parse::DirectoryOwnership>,
-    can_reset_parser_errors: Rc<RefCell<bool>>,
-) -> Result<ast::Crate, ErrorKind> {
-    let input_is_stdin = input.is_text();
-
-    let parser = match input {
-        Input::File(ref file) => {
-            // Use `new_sub_parser_from_file` when we the input is a submodule.
-            Ok(if let Some(dir_own) = directory_ownership {
-                rustc_parse::new_sub_parser_from_file(parse_session, file, dir_own, None, DUMMY_SP)
-            } else {
-                rustc_parse::new_parser_from_file(parse_session, file)
-            })
-        }
-        Input::Text(text) => rustc_parse::maybe_new_parser_from_source_str(
-            parse_session,
-            rustc_span::FileName::Custom("stdin".to_owned()),
-            text,
-        )
-        .map(|mut parser| {
-            parser.recurse_into_file_modules = false;
-            parser
-        }),
-    };
-
-    let result = match parser {
-        Ok(mut parser) => {
-            parser.cfg_mods = false;
-            if config.skip_children() {
-                parser.recurse_into_file_modules = false;
-            }
-
-            let mut parser = AssertUnwindSafe(parser);
-            catch_unwind(move || parser.0.parse_crate_mod().map_err(|d| vec![d]))
-        }
-        Err(diagnostics) => {
-            for diagnostic in diagnostics {
-                parse_session.span_diagnostic.emit_diagnostic(&diagnostic);
-            }
-            report.add_parsing_error();
-            return Err(ErrorKind::ParseError);
-        }
-    };
-
-    match result {
-        Ok(Ok(c)) => {
-            if !parse_session.span_diagnostic.has_errors() {
-                return Ok(c);
-            }
-            // This scenario occurs when the parser encountered errors
-            // but was still able to recover. If all of the parser errors
-            // occurred in files that are ignored, then reset
-            // the error count and continue.
-            // https://github.com/rust-lang/rustfmt/issues/3779
-            if *can_reset_parser_errors.borrow() {
-                parse_session.span_diagnostic.reset_err_count();
-                return Ok(c);
-            }
-        }
-        Ok(Err(mut diagnostics)) => diagnostics.iter_mut().for_each(DiagnosticBuilder::emit),
-        Err(_) => {
-            // Note that if you see this message and want more information,
-            // then run the `parse_crate_mod` function above without
-            // `catch_unwind` so rustfmt panics and you can get a backtrace.
-            should_emit_verbose(input_is_stdin, config, || {
-                println!("The Rust parser panicked")
-            });
-        }
-    }
-
-    report.add_parsing_error();
-    Err(ErrorKind::ParseError)
-}
-
-struct SilentOnIgnoredFilesEmitter {
-    ignore_path_set: Rc<IgnorePathSet>,
-    source_map: Rc<SourceMap>,
-    emitter: Box<dyn Emitter + Send>,
-    has_non_ignorable_parser_errors: bool,
-    can_reset: Rc<RefCell<bool>>,
-}
-
-impl SilentOnIgnoredFilesEmitter {
-    fn handle_non_ignoreable_error(&mut self, db: &Diagnostic) {
-        self.has_non_ignorable_parser_errors = true;
-        *self.can_reset.borrow_mut() = false;
-        self.emitter.emit_diagnostic(db);
-    }
-}
-
-impl Emitter for SilentOnIgnoredFilesEmitter {
-    fn source_map(&self) -> Option<&Lrc<SourceMap>> {
-        None
-    }
-
-    fn emit_diagnostic(&mut self, db: &Diagnostic) {
-        if db.level == DiagnosticLevel::Fatal {
-            return self.handle_non_ignoreable_error(db);
-        }
-        if let Some(primary_span) = &db.span.primary_span() {
-            let file_name = self.source_map.span_to_filename(*primary_span);
-            if let rustc_span::FileName::Real(ref path) = file_name {
-                if self
-                    .ignore_path_set
-                    .is_match(&FileName::Real(path.to_path_buf()))
-                {
-                    if !self.has_non_ignorable_parser_errors {
-                        *self.can_reset.borrow_mut() = true;
-                    }
-                    return;
-                }
-            };
-        }
-        self.handle_non_ignoreable_error(db);
-    }
-}
-
-/// Emitter which discards every error.
-struct SilentEmitter;
-
-impl Emitter for SilentEmitter {
-    fn source_map(&self) -> Option<&Lrc<SourceMap>> {
-        None
-    }
-    fn emit_diagnostic(&mut self, _db: &Diagnostic) {}
-}
-
-fn silent_emitter() -> Box<dyn Emitter + Send> {
-    Box::new(SilentEmitter {})
-}
-
-fn make_parse_sess(
-    source_map: Rc<SourceMap>,
-    config: &Config,
-    ignore_path_set: Rc<IgnorePathSet>,
-    can_reset: Rc<RefCell<bool>>,
-) -> ParseSess {
-    let supports_color = term::stderr().map_or(false, |term| term.supports_color());
-    let color_cfg = if supports_color {
-        ColorConfig::Auto
-    } else {
-        ColorConfig::Never
-    };
-
-    let emitter = if config.hide_parse_errors() {
-        silent_emitter()
-    } else {
-        Box::new(EmitterWriter::stderr(
-            color_cfg,
-            Some(source_map.clone()),
-            false,
-            false,
-            None,
-            false,
-        ))
-    };
-    let handler = Handler::with_emitter(
-        true,
-        None,
-        Box::new(SilentOnIgnoredFilesEmitter {
-            has_non_ignorable_parser_errors: false,
-            source_map: source_map.clone(),
-            emitter,
-            ignore_path_set,
-            can_reset,
-        }),
-    );
-
-    ParseSess::with_span_handler(handler, source_map)
-}
-
-fn should_emit_verbose<F>(is_stdin: bool, config: &Config, f: F)
+fn should_emit_verbose<F>(forbid_verbose_output: bool, config: &Config, f: F)
 where
     F: Fn(),
 {
-    if config.verbose() == Verbosity::Verbose && !is_stdin {
+    if config.verbose() == Verbosity::Verbose && !forbid_verbose_output {
         f();
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    mod emitter {
-        use super::*;
-        use crate::config::IgnoreList;
-        use crate::is_nightly_channel;
-        use crate::utils::mk_sp;
-        use rustc_span::{BytePos, FileName as SourceMapFileName, MultiSpan, DUMMY_SP};
-        use std::path::{Path, PathBuf};
-
-        struct TestEmitter {
-            num_emitted_errors: Rc<RefCell<u32>>,
-        }
-
-        impl Emitter for TestEmitter {
-            fn source_map(&self) -> Option<&Lrc<SourceMap>> {
-                None
-            }
-            fn emit_diagnostic(&mut self, _db: &Diagnostic) {
-                *self.num_emitted_errors.borrow_mut() += 1;
-            }
-        }
-
-        fn build_diagnostic(level: DiagnosticLevel, span: Option<MultiSpan>) -> Diagnostic {
-            Diagnostic {
-                level,
-                code: None,
-                message: vec![],
-                children: vec![],
-                suggestions: vec![],
-                span: span.unwrap_or_else(MultiSpan::new),
-                sort_span: DUMMY_SP,
-            }
-        }
-
-        fn build_emitter(
-            num_emitted_errors: Rc<RefCell<u32>>,
-            can_reset: Rc<RefCell<bool>>,
-            source_map: Option<Rc<SourceMap>>,
-            ignore_list: Option<IgnoreList>,
-        ) -> SilentOnIgnoredFilesEmitter {
-            let emitter_writer = TestEmitter { num_emitted_errors };
-            let source_map =
-                source_map.unwrap_or_else(|| Rc::new(SourceMap::new(FilePathMapping::empty())));
-            let ignore_path_set =
-                Rc::new(IgnorePathSet::from_ignore_list(&ignore_list.unwrap_or_default()).unwrap());
-            SilentOnIgnoredFilesEmitter {
-                has_non_ignorable_parser_errors: false,
-                source_map,
-                emitter: Box::new(emitter_writer),
-                ignore_path_set,
-                can_reset,
-            }
-        }
-
-        fn get_ignore_list(config: &str) -> IgnoreList {
-            Config::from_toml(config, Path::new("")).unwrap().ignore()
-        }
-
-        #[test]
-        fn handles_fatal_parse_error_in_ignored_file() {
-            let num_emitted_errors = Rc::new(RefCell::new(0));
-            let can_reset_errors = Rc::new(RefCell::new(false));
-            let ignore_list = get_ignore_list(r#"ignore = ["foo.rs"]"#);
-            let source_map = Rc::new(SourceMap::new(FilePathMapping::empty()));
-            let source =
-                String::from(r#"extern "system" fn jni_symbol!( funcName ) ( ... ) -> {} "#);
-            source_map.new_source_file(SourceMapFileName::Real(PathBuf::from("foo.rs")), source);
-            let mut emitter = build_emitter(
-                Rc::clone(&num_emitted_errors),
-                Rc::clone(&can_reset_errors),
-                Some(Rc::clone(&source_map)),
-                Some(ignore_list),
-            );
-            let span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1)));
-            let fatal_diagnostic = build_diagnostic(DiagnosticLevel::Fatal, Some(span));
-            emitter.emit_diagnostic(&fatal_diagnostic);
-            assert_eq!(*num_emitted_errors.borrow(), 1);
-            assert_eq!(*can_reset_errors.borrow(), false);
-        }
-
-        #[test]
-        fn handles_recoverable_parse_error_in_ignored_file() {
-            if !is_nightly_channel!() {
-                return;
-            }
-            let num_emitted_errors = Rc::new(RefCell::new(0));
-            let can_reset_errors = Rc::new(RefCell::new(false));
-            let ignore_list = get_ignore_list(r#"ignore = ["foo.rs"]"#);
-            let source_map = Rc::new(SourceMap::new(FilePathMapping::empty()));
-            let source = String::from(r#"pub fn bar() { 1x; }"#);
-            source_map.new_source_file(SourceMapFileName::Real(PathBuf::from("foo.rs")), source);
-            let mut emitter = build_emitter(
-                Rc::clone(&num_emitted_errors),
-                Rc::clone(&can_reset_errors),
-                Some(Rc::clone(&source_map)),
-                Some(ignore_list),
-            );
-            let span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1)));
-            let non_fatal_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(span));
-            emitter.emit_diagnostic(&non_fatal_diagnostic);
-            assert_eq!(*num_emitted_errors.borrow(), 0);
-            assert_eq!(*can_reset_errors.borrow(), true);
-        }
-
-        #[test]
-        fn handles_recoverable_parse_error_in_non_ignored_file() {
-            if !is_nightly_channel!() {
-                return;
-            }
-            let num_emitted_errors = Rc::new(RefCell::new(0));
-            let can_reset_errors = Rc::new(RefCell::new(false));
-            let source_map = Rc::new(SourceMap::new(FilePathMapping::empty()));
-            let source = String::from(r#"pub fn bar() { 1x; }"#);
-            source_map.new_source_file(SourceMapFileName::Real(PathBuf::from("foo.rs")), source);
-            let mut emitter = build_emitter(
-                Rc::clone(&num_emitted_errors),
-                Rc::clone(&can_reset_errors),
-                Some(Rc::clone(&source_map)),
-                None,
-            );
-            let span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1)));
-            let non_fatal_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(span));
-            emitter.emit_diagnostic(&non_fatal_diagnostic);
-            assert_eq!(*num_emitted_errors.borrow(), 1);
-            assert_eq!(*can_reset_errors.borrow(), false);
-        }
-
-        #[test]
-        fn handles_mix_of_recoverable_parse_error() {
-            if !is_nightly_channel!() {
-                return;
-            }
-            let num_emitted_errors = Rc::new(RefCell::new(0));
-            let can_reset_errors = Rc::new(RefCell::new(false));
-            let source_map = Rc::new(SourceMap::new(FilePathMapping::empty()));
-            let ignore_list = get_ignore_list(r#"ignore = ["foo.rs"]"#);
-            let bar_source = String::from(r#"pub fn bar() { 1x; }"#);
-            let foo_source = String::from(r#"pub fn foo() { 1x; }"#);
-            let fatal_source =
-                String::from(r#"extern "system" fn jni_symbol!( funcName ) ( ... ) -> {} "#);
-            source_map
-                .new_source_file(SourceMapFileName::Real(PathBuf::from("bar.rs")), bar_source);
-            source_map
-                .new_source_file(SourceMapFileName::Real(PathBuf::from("foo.rs")), foo_source);
-            source_map.new_source_file(
-                SourceMapFileName::Real(PathBuf::from("fatal.rs")),
-                fatal_source,
-            );
-            let mut emitter = build_emitter(
-                Rc::clone(&num_emitted_errors),
-                Rc::clone(&can_reset_errors),
-                Some(Rc::clone(&source_map)),
-                Some(ignore_list),
-            );
-            let bar_span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1)));
-            let foo_span = MultiSpan::from_span(mk_sp(BytePos(21), BytePos(22)));
-            let bar_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(bar_span));
-            let foo_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(foo_span));
-            let fatal_diagnostic = build_diagnostic(DiagnosticLevel::Fatal, None);
-            emitter.emit_diagnostic(&bar_diagnostic);
-            emitter.emit_diagnostic(&foo_diagnostic);
-            emitter.emit_diagnostic(&fatal_diagnostic);
-            assert_eq!(*num_emitted_errors.borrow(), 2);
-            assert_eq!(*can_reset_errors.borrow(), false);
-        }
-    }
-}
diff --git a/src/imports.rs b/src/imports.rs
index 9c914ce476d..d8f963e1ec3 100644
--- a/src/imports.rs
+++ b/src/imports.rs
@@ -2,8 +2,8 @@ use std::borrow::Cow;
 use std::cmp::Ordering;
 use std::fmt;
 
+use rustc_ast::ast::{self, UseTreeKind};
 use rustc_span::{source_map, symbol::sym, BytePos, Span, DUMMY_SP};
-use syntax::ast::{self, UseTreeKind};
 
 use crate::comment::combine_strs_with_missing_comments;
 use crate::config::lists::*;
diff --git a/src/items.rs b/src/items.rs
index 0316dc6f0c2..baa993590ca 100644
--- a/src/items.rs
+++ b/src/items.rs
@@ -4,9 +4,9 @@ use std::borrow::Cow;
 use std::cmp::{max, min, Ordering};
 
 use regex::Regex;
+use rustc_ast::visit;
+use rustc_ast::{ast, ptr};
 use rustc_span::{source_map, symbol, BytePos, Span, DUMMY_SP};
-use syntax::visit;
-use syntax::{ast, ptr};
 
 use crate::attr::filter_inline_attrs;
 use crate::comment::{
@@ -165,10 +165,10 @@ pub(crate) struct FnSig<'a> {
     decl: &'a ast::FnDecl,
     generics: &'a ast::Generics,
     ext: ast::Extern,
-    is_async: Cow<'a, ast::IsAsync>,
-    constness: ast::Constness,
+    is_async: Cow<'a, ast::Async>,
+    constness: ast::Const,
     defaultness: ast::Defaultness,
-    unsafety: ast::Unsafety,
+    unsafety: ast::Unsafe,
     visibility: ast::Visibility,
 }
 
@@ -182,10 +182,10 @@ impl<'a> FnSig<'a> {
             decl,
             generics,
             ext: ast::Extern::None,
-            is_async: Cow::Owned(ast::IsAsync::NotAsync),
-            constness: ast::Constness::NotConst,
+            is_async: Cow::Owned(ast::Async::No),
+            constness: ast::Const::No,
             defaultness: ast::Defaultness::Final,
-            unsafety: ast::Unsafety::Normal,
+            unsafety: ast::Unsafe::No,
             visibility: vis,
         }
     }
@@ -196,8 +196,8 @@ impl<'a> FnSig<'a> {
     ) -> FnSig<'a> {
         FnSig {
             unsafety: method_sig.header.unsafety,
-            is_async: Cow::Borrowed(&method_sig.header.asyncness.node),
-            constness: method_sig.header.constness.node,
+            is_async: Cow::Borrowed(&method_sig.header.asyncness),
+            constness: method_sig.header.constness,
             defaultness: ast::Defaultness::Final,
             ext: method_sig.header.ext,
             decl: &*method_sig.decl,
@@ -224,8 +224,8 @@ impl<'a> FnSig<'a> {
                     decl,
                     generics,
                     ext: fn_sig.header.ext,
-                    constness: fn_sig.header.constness.node,
-                    is_async: Cow::Borrowed(&fn_sig.header.asyncness.node),
+                    constness: fn_sig.header.constness,
+                    is_async: Cow::Borrowed(&fn_sig.header.asyncness),
                     defaultness,
                     unsafety: fn_sig.header.unsafety,
                     visibility: vis.clone(),
@@ -298,8 +298,14 @@ impl<'a> FmtVisitor<'a> {
 
     fn format_foreign_item(&mut self, item: &ast::ForeignItem) {
         let rewrite = item.rewrite(&self.get_context(), self.shape());
-        self.push_rewrite(item.span(), rewrite);
-        self.last_pos = item.span.hi();
+        let hi = item.span.hi();
+        let span = if item.attrs.is_empty() {
+            item.span
+        } else {
+            mk_sp(item.attrs[0].span.lo(), hi)
+        };
+        self.push_rewrite(span, rewrite);
+        self.last_pos = hi;
     }
 
     pub(crate) fn rewrite_fn_before_block(
@@ -363,17 +369,17 @@ impl<'a> FmtVisitor<'a> {
             return None;
         }
 
-        let source_map = self.get_context().source_map;
+        let context = self.get_context();
 
         if self.config.empty_item_single_line()
-            && is_empty_block(block, None, source_map)
+            && is_empty_block(&context, block, None)
             && self.block_indent.width() + fn_str.len() + 3 <= self.config.max_width()
             && !last_line_contains_single_line_comment(fn_str)
         {
             return Some(format!("{} {{}}", fn_str));
         }
 
-        if !self.config.fn_single_line() || !is_simple_block_stmt(block, None, source_map) {
+        if !self.config.fn_single_line() || !is_simple_block_stmt(&context, block, None) {
             return None;
         }
 
@@ -588,7 +594,7 @@ impl<'a> FmtVisitor<'a> {
                 self.buffer.clear();
             }
 
-            fn is_type(ty: &Option<syntax::ptr::P<ast::Ty>>) -> bool {
+            fn is_type(ty: &Option<rustc_ast::ptr::P<ast::Ty>>) -> bool {
                 match ty {
                     None => true,
                     Some(lty) => match lty.kind.opaque_top_hack() {
@@ -598,7 +604,7 @@ impl<'a> FmtVisitor<'a> {
                 }
             }
 
-            fn is_opaque(ty: &Option<syntax::ptr::P<ast::Ty>>) -> bool {
+            fn is_opaque(ty: &Option<rustc_ast::ptr::P<ast::Ty>>) -> bool {
                 match ty {
                     None => false,
                     Some(lty) => match lty.kind.opaque_top_hack() {
@@ -609,15 +615,15 @@ impl<'a> FmtVisitor<'a> {
             }
 
             fn both_type(
-                a: &Option<syntax::ptr::P<ast::Ty>>,
-                b: &Option<syntax::ptr::P<ast::Ty>>,
+                a: &Option<rustc_ast::ptr::P<ast::Ty>>,
+                b: &Option<rustc_ast::ptr::P<ast::Ty>>,
             ) -> bool {
                 is_type(a) && is_type(b)
             }
 
             fn both_opaque(
-                a: &Option<syntax::ptr::P<ast::Ty>>,
-                b: &Option<syntax::ptr::P<ast::Ty>>,
+                a: &Option<rustc_ast::ptr::P<ast::Ty>>,
+                b: &Option<rustc_ast::ptr::P<ast::Ty>>,
             ) -> bool {
                 is_opaque(a) && is_opaque(b)
             }
@@ -629,7 +635,7 @@ impl<'a> FmtVisitor<'a> {
             use crate::ast::AssocItemKind::*;
             fn need_empty_line(a: &ast::AssocItemKind, b: &ast::AssocItemKind) -> bool {
                 match (a, b) {
-                    (TyAlias(_, ref lty), TyAlias(_, ref rty))
+                    (TyAlias(_, _, _, ref lty), TyAlias(_, _, _, ref rty))
                         if both_type(lty, rty) || both_opaque(lty, rty) =>
                     {
                         false
@@ -640,23 +646,23 @@ impl<'a> FmtVisitor<'a> {
             }
 
             buffer.sort_by(|(_, a), (_, b)| match (&a.kind, &b.kind) {
-                (TyAlias(_, ref lty), TyAlias(_, ref rty))
+                (TyAlias(_, _, _, ref lty), TyAlias(_, _, _, ref rty))
                     if both_type(lty, rty) || both_opaque(lty, rty) =>
                 {
                     a.ident.as_str().cmp(&b.ident.as_str())
                 }
-                (Const(..), Const(..)) | (Macro(..), Macro(..)) => {
+                (Const(..), Const(..)) | (MacCall(..), MacCall(..)) => {
                     a.ident.as_str().cmp(&b.ident.as_str())
                 }
                 (Fn(..), Fn(..)) => a.span.lo().cmp(&b.span.lo()),
-                (TyAlias(_, ref ty), _) if is_type(ty) => Ordering::Less,
-                (_, TyAlias(_, ref ty)) if is_type(ty) => Ordering::Greater,
+                (TyAlias(_, _, _, ref ty), _) if is_type(ty) => Ordering::Less,
+                (_, TyAlias(_, _, _, ref ty)) if is_type(ty) => Ordering::Greater,
                 (TyAlias(..), _) => Ordering::Less,
                 (_, TyAlias(..)) => Ordering::Greater,
                 (Const(..), _) => Ordering::Less,
                 (_, Const(..)) => Ordering::Greater,
-                (Macro(..), _) => Ordering::Less,
-                (_, Macro(..)) => Ordering::Greater,
+                (MacCall(..), _) => Ordering::Less,
+                (_, MacCall(..)) => Ordering::Greater,
             });
             let mut prev_kind = None;
             for (buf, item) in buffer {
@@ -868,10 +874,9 @@ fn format_impl_ref_and_type(
         let generics_str = rewrite_generics(context, "impl", generics, shape)?;
         result.push_str(&generics_str);
 
-        let polarity_str = if polarity == ast::ImplPolarity::Negative {
-            "!"
-        } else {
-            ""
+        let polarity_str = match polarity {
+            ast::ImplPolarity::Negative(_) => "!",
+            ast::ImplPolarity::Positive => "",
         };
 
         if let Some(ref trait_ref) = *trait_ref {
@@ -1714,9 +1719,13 @@ pub(crate) struct StaticParts<'a> {
 
 impl<'a> StaticParts<'a> {
     pub(crate) fn from_item(item: &'a ast::Item) -> Self {
-        let (prefix, ty, mutability, expr) = match item.kind {
-            ast::ItemKind::Static(ref ty, mutability, ref expr) => ("static", ty, mutability, expr),
-            ast::ItemKind::Const(ref ty, ref expr) => ("const", ty, ast::Mutability::Not, expr),
+        let (defaultness, prefix, ty, mutability, expr) = match item.kind {
+            ast::ItemKind::Static(ref ty, mutability, ref expr) => {
+                (None, "static", ty, mutability, expr)
+            }
+            ast::ItemKind::Const(defaultness, ref ty, ref expr) => {
+                (Some(defaultness), "const", ty, ast::Mutability::Not, expr)
+            }
             _ => unreachable!(),
         };
         StaticParts {
@@ -1725,15 +1734,17 @@ impl<'a> StaticParts<'a> {
             ident: item.ident,
             ty,
             mutability,
-            expr_opt: Some(expr),
-            defaultness: None,
+            expr_opt: expr.as_ref(),
+            defaultness,
             span: item.span,
         }
     }
 
     pub(crate) fn from_trait_item(ti: &'a ast::AssocItem) -> Self {
-        let (ty, expr_opt) = match ti.kind {
-            ast::AssocItemKind::Const(ref ty, ref expr_opt) => (ty, expr_opt),
+        let (defaultness, ty, expr_opt) = match ti.kind {
+            ast::AssocItemKind::Const(defaultness, ref ty, ref expr_opt) => {
+                (defaultness, ty, expr_opt)
+            }
             _ => unreachable!(),
         };
         StaticParts {
@@ -1743,14 +1754,14 @@ impl<'a> StaticParts<'a> {
             ty,
             mutability: ast::Mutability::Not,
             expr_opt: expr_opt.as_ref(),
-            defaultness: None,
+            defaultness: Some(defaultness),
             span: ti.span,
         }
     }
 
     pub(crate) fn from_impl_item(ii: &'a ast::AssocItem) -> Self {
-        let (ty, expr) = match ii.kind {
-            ast::AssocItemKind::Const(ref ty, ref expr) => (ty, expr),
+        let (defaultness, ty, expr) = match ii.kind {
+            ast::AssocItemKind::Const(defaultness, ref ty, ref expr) => (defaultness, ty, expr),
             _ => unreachable!(),
         };
         StaticParts {
@@ -1760,7 +1771,7 @@ impl<'a> StaticParts<'a> {
             ty,
             mutability: ast::Mutability::Not,
             expr_opt: expr.as_ref(),
-            defaultness: Some(ii.defaultness),
+            defaultness: Some(defaultness),
             span: ii.span,
         }
     }
@@ -1903,16 +1914,16 @@ pub(crate) fn rewrite_associated_impl_type(
     let result = rewrite_associated_type(ident, ty_opt, generics, None, context, indent)?;
 
     match defaultness {
-        ast::Defaultness::Default => Some(format!("default {}", result)),
+        ast::Defaultness::Default(..) => Some(format!("default {}", result)),
         _ => Some(result),
     }
 }
 
-impl Rewrite for ast::FunctionRetTy {
+impl Rewrite for ast::FnRetTy {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
         match *self {
-            ast::FunctionRetTy::Default(_) => Some(String::new()),
-            ast::FunctionRetTy::Ty(ref ty) => {
+            ast::FnRetTy::Default(_) => Some(String::new()),
+            ast::FnRetTy::Ty(ref ty) => {
                 if context.config.version() == Version::One
                     || context.config.indent_style() == IndentStyle::Visual
                 {
@@ -2290,7 +2301,7 @@ fn rewrite_fn_base(
     }
 
     // Return type.
-    if let ast::FunctionRetTy::Ty(..) = fd.output {
+    if let ast::FnRetTy::Ty(..) = fd.output {
         let ret_should_indent = match context.config.indent_style() {
             // If our params are block layout then we surely must have space.
             IndentStyle::Block if put_params_in_block || fd.inputs.is_empty() => false,
@@ -2396,8 +2407,8 @@ fn rewrite_fn_base(
     }
 
     let pos_before_where = match fd.output {
-        ast::FunctionRetTy::Default(..) => params_span.hi(),
-        ast::FunctionRetTy::Ty(ref ty) => ty.span.hi(),
+        ast::FnRetTy::Default(..) => params_span.hi(),
+        ast::FnRetTy::Ty(ref ty) => ty.span.hi(),
     };
 
     let is_params_multi_lined = param_str.contains('\n');
@@ -2425,7 +2436,7 @@ fn rewrite_fn_base(
     // If there are neither where-clause nor return type, we may be missing comments between
     // params and `{`.
     if where_clause_str.is_empty() {
-        if let ast::FunctionRetTy::Default(ret_span) = fd.output {
+        if let ast::FnRetTy::Default(ret_span) = fd.output {
             match recover_missing_comment_in_span(
                 mk_sp(params_span.hi(), ret_span.hi()),
                 shape,
@@ -3083,7 +3094,7 @@ impl Rewrite for ast::ForeignItem {
         let span = mk_sp(self.span.lo(), self.span.hi() - BytePos(1));
 
         let item_str = match self.kind {
-            ast::ForeignItemKind::Fn(ref fn_sig, ref generics, _) => rewrite_fn_base(
+            ast::ForeignItemKind::Fn(_, ref fn_sig, ref generics, _) => rewrite_fn_base(
                 context,
                 shape.indent,
                 self.ident,
@@ -3092,7 +3103,7 @@ impl Rewrite for ast::ForeignItem {
                 FnBraceStyle::None,
             )
             .map(|(s, _)| format!("{};", s)),
-            ast::ForeignItemKind::Static(ref ty, mutability) => {
+            ast::ForeignItemKind::Static(ref ty, mutability, _) => {
                 // FIXME(#21): we're dropping potential comments in between the
                 // function kw here.
                 let vis = format_visibility(context, &self.vis);
@@ -3106,7 +3117,7 @@ impl Rewrite for ast::ForeignItem {
                 // 1 = ;
                 rewrite_assign_rhs(context, prefix, &**ty, shape.sub_width(1)?).map(|s| s + ";")
             }
-            ast::ForeignItemKind::Ty => {
+            ast::ForeignItemKind::TyAlias(..) => {
                 let vis = format_visibility(context, &self.vis);
                 Some(format!(
                     "{}type {};",
@@ -3114,7 +3125,7 @@ impl Rewrite for ast::ForeignItem {
                     rewrite_ident(context, self.ident)
                 ))
             }
-            ast::ForeignItemKind::Macro(ref mac) => {
+            ast::ForeignItemKind::MacCall(ref mac) => {
                 rewrite_macro(mac, None, context, shape, MacroPosition::Item)
             }
         }?;
diff --git a/src/lib.rs b/src/lib.rs
index f0783b2ca36..ecf19ebb586 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -3,7 +3,6 @@
 
 #[macro_use]
 extern crate derive_new;
-#[cfg(test)]
 #[macro_use]
 extern crate lazy_static;
 #[macro_use]
@@ -20,14 +19,14 @@ use std::rc::Rc;
 
 use failure::Fail;
 use ignore;
-use rustc_parse::DirectoryOwnership;
-use syntax::ast;
+use rustc_ast::ast;
 
 use crate::comment::LineClasses;
 use crate::emitter::Emitter;
 use crate::formatting::{FormatErrorMap, FormattingError, ReportedErrors, SourceFile};
 use crate::issues::Issue;
 use crate::shape::Indent;
+use crate::syntux::parser::DirectoryOwnership;
 use crate::utils::indent_next_line;
 
 pub use crate::config::{
@@ -75,6 +74,7 @@ pub(crate) mod source_map;
 mod spanned;
 mod stmt;
 mod string;
+mod syntux;
 #[cfg(test)]
 mod test;
 mod types;
@@ -509,13 +509,6 @@ pub enum Input {
 }
 
 impl Input {
-    fn is_text(&self) -> bool {
-        match *self {
-            Input::File(_) => false,
-            Input::Text(_) => true,
-        }
-    }
-
     fn file_name(&self) -> FileName {
         match *self {
             Input::File(ref file) => FileName::Real(file.clone()),
diff --git a/src/lists.rs b/src/lists.rs
index 96a10924e25..bc55ef6686a 100644
--- a/src/lists.rs
+++ b/src/lists.rs
@@ -560,7 +560,7 @@ pub(crate) struct ListItems<'a, I, F1, F2, F3>
 where
     I: Iterator,
 {
-    snippet_provider: &'a SnippetProvider<'a>,
+    snippet_provider: &'a SnippetProvider,
     inner: Peekable<I>,
     get_lo: F1,
     get_hi: F2,
@@ -777,7 +777,7 @@ where
 #[allow(clippy::too_many_arguments)]
 // Creates an iterator over a list's items with associated comments.
 pub(crate) fn itemize_list<'a, T, I, F1, F2, F3>(
-    snippet_provider: &'a SnippetProvider<'_>,
+    snippet_provider: &'a SnippetProvider,
     inner: I,
     terminator: &'a str,
     separator: &'a str,
diff --git a/src/macros.rs b/src/macros.rs
index dea056928d9..400daa6a5aa 100644
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -12,12 +12,12 @@
 use std::collections::HashMap;
 use std::panic::{catch_unwind, AssertUnwindSafe};
 
+use rustc_ast::token::{BinOpToken, DelimToken, Token, TokenKind};
+use rustc_ast::tokenstream::{Cursor, TokenStream, TokenTree};
+use rustc_ast::{ast, ptr};
 use rustc_ast_pretty::pprust;
 use rustc_parse::{new_parser_from_tts, parser::Parser};
 use rustc_span::{symbol::kw, BytePos, Span, Symbol, DUMMY_SP};
-use syntax::token::{BinOpToken, DelimToken, Token, TokenKind};
-use syntax::tokenstream::{Cursor, TokenStream, TokenTree};
-use syntax::{ast, ptr};
 
 use crate::comment::{
     contains_comment, CharClasses, FindUncommented, FullCodeCharKind, LineClasses,
@@ -178,8 +178,8 @@ fn return_macro_parse_failure_fallback(
     }
 
     context.skipped_range.borrow_mut().push((
-        context.source_map.lookup_line(span.lo()).unwrap().line,
-        context.source_map.lookup_line(span.hi()).unwrap().line,
+        context.parse_sess.line_of_byte_pos(span.lo()),
+        context.parse_sess.line_of_byte_pos(span.hi()),
     ));
 
     // Return the snippet unmodified if the macro is not block-like
@@ -187,7 +187,7 @@ fn return_macro_parse_failure_fallback(
 }
 
 pub(crate) fn rewrite_macro(
-    mac: &ast::Mac,
+    mac: &ast::MacCall,
     extra_ident: Option<ast::Ident>,
     context: &RewriteContext<'_>,
     shape: Shape,
@@ -231,7 +231,7 @@ fn check_keyword<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option<MacroArg> {
         {
             parser.bump();
             let macro_arg =
-                MacroArg::Keyword(ast::Ident::with_dummy_span(keyword), parser.prev_span);
+                MacroArg::Keyword(ast::Ident::with_dummy_span(keyword), parser.prev_token.span);
             return Some(macro_arg);
         }
     }
@@ -239,7 +239,7 @@ fn check_keyword<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option<MacroArg> {
 }
 
 fn rewrite_macro_inner(
-    mac: &ast::Mac,
+    mac: &ast::MacCall,
     extra_ident: Option<ast::Ident>,
     context: &RewriteContext<'_>,
     shape: Shape,
@@ -286,7 +286,7 @@ fn rewrite_macro_inner(
         }
     }
 
-    let mut parser = new_parser_from_tts(context.parse_session, ts.trees().collect());
+    let mut parser = new_parser_from_tts(context.parse_sess.inner(), ts.trees().collect());
     let mut arg_vec = Vec::new();
     let mut vec_with_semi = false;
     let mut trailing_comma = false;
@@ -495,7 +495,7 @@ pub(crate) fn rewrite_macro_def(
         None => return snippet,
     };
 
-    let mut result = if def.legacy {
+    let mut result = if def.macro_rules {
         String::from("macro_rules!")
     } else {
         format!("{}macro", format_visibility(context, vis))
@@ -504,7 +504,7 @@ pub(crate) fn rewrite_macro_def(
     result += " ";
     result += rewrite_ident(context, ident);
 
-    let multi_branch_style = def.legacy || parsed_def.branches.len() != 1;
+    let multi_branch_style = def.macro_rules || parsed_def.branches.len() != 1;
 
     let arm_shape = if multi_branch_style {
         shape
@@ -537,7 +537,7 @@ pub(crate) fn rewrite_macro_def(
     .collect::<Vec<_>>();
 
     let fmt = ListFormatting::new(arm_shape, context.config)
-        .separator(if def.legacy { ";" } else { "" })
+        .separator(if def.macro_rules { ";" } else { "" })
         .trailing_separator(SeparatorTactic::Always)
         .preserve_newline(true);
 
@@ -1186,11 +1186,14 @@ fn next_space(tok: &TokenKind) -> SpaceState {
 /// Tries to convert a macro use into a short hand try expression. Returns `None`
 /// when the macro is not an instance of `try!` (or parsing the inner expression
 /// failed).
-pub(crate) fn convert_try_mac(mac: &ast::Mac, context: &RewriteContext<'_>) -> Option<ast::Expr> {
+pub(crate) fn convert_try_mac(
+    mac: &ast::MacCall,
+    context: &RewriteContext<'_>,
+) -> Option<ast::Expr> {
     let path = &pprust::path_to_string(&mac.path);
     if path == "try" || path == "r#try" {
         let ts = mac.args.inner_tokens();
-        let mut parser = new_parser_from_tts(context.parse_session, ts.trees().collect());
+        let mut parser = new_parser_from_tts(context.parse_sess.inner(), ts.trees().collect());
 
         Some(ast::Expr {
             id: ast::NodeId::root(), // dummy value
@@ -1203,7 +1206,7 @@ pub(crate) fn convert_try_mac(mac: &ast::Mac, context: &RewriteContext<'_>) -> O
     }
 }
 
-pub(crate) fn macro_style(mac: &ast::Mac, context: &RewriteContext<'_>) -> DelimToken {
+pub(crate) fn macro_style(mac: &ast::MacCall, context: &RewriteContext<'_>) -> DelimToken {
     let snippet = context.snippet(mac.span());
     let paren_pos = snippet.find_uncommented("(").unwrap_or(usize::max_value());
     let bracket_pos = snippet.find_uncommented("[").unwrap_or(usize::max_value());
@@ -1422,7 +1425,7 @@ fn format_lazy_static(
     ts: &TokenStream,
 ) -> Option<String> {
     let mut result = String::with_capacity(1024);
-    let mut parser = new_parser_from_tts(context.parse_session, ts.trees().collect());
+    let mut parser = new_parser_from_tts(context.parse_sess.inner(), ts.trees().collect());
     let nested_shape = shape
         .block_indent(context.config.tab_spaces())
         .with_max_width(context.config);
diff --git a/src/matches.rs b/src/matches.rs
index 954db40ae52..c6b17122326 100644
--- a/src/matches.rs
+++ b/src/matches.rs
@@ -2,8 +2,8 @@
 
 use std::iter::repeat;
 
+use rustc_ast::{ast, ptr};
 use rustc_span::{BytePos, Span};
-use syntax::{ast, ptr};
 
 use crate::comment::{combine_strs_with_missing_comments, rewrite_comment};
 use crate::config::lists::*;
@@ -276,7 +276,7 @@ fn block_can_be_flattened<'a>(
         ast::ExprKind::Block(ref block, _)
             if !is_unsafe_block(block)
                 && !context.inside_macro()
-                && is_simple_block(block, Some(&expr.attrs), context.source_map) =>
+                && is_simple_block(context, block, Some(&expr.attrs)) =>
         {
             Some(&*block)
         }
@@ -332,10 +332,7 @@ fn rewrite_match_body(
         shape.offset_left(extra_offset(pats_str, shape) + 4),
     );
     let (is_block, is_empty_block) = if let ast::ExprKind::Block(ref block, _) = body.kind {
-        (
-            true,
-            is_empty_block(block, Some(&body.attrs), context.source_map),
-        )
+        (true, is_empty_block(context, block, Some(&body.attrs)))
     } else {
         (false, false)
     };
@@ -562,7 +559,7 @@ fn can_flatten_block_around_this(body: &ast::Expr) -> bool {
         | ast::ExprKind::Array(..)
         | ast::ExprKind::Call(..)
         | ast::ExprKind::MethodCall(..)
-        | ast::ExprKind::Mac(..)
+        | ast::ExprKind::MacCall(..)
         | ast::ExprKind::Struct(..)
         | ast::ExprKind::Tup(..) => true,
         ast::ExprKind::AddrOf(_, _, ref expr)
diff --git a/src/missed_spans.rs b/src/missed_spans.rs
index 99595436f89..e6889ae9786 100644
--- a/src/missed_spans.rs
+++ b/src/missed_spans.rs
@@ -86,9 +86,8 @@ impl<'a> FmtVisitor<'a> {
 
         assert!(
             start < end,
-            "Request to format inverted span: {:?} to {:?}",
-            self.source_map.lookup_char_pos(start),
-            self.source_map.lookup_char_pos(end)
+            "Request to format inverted span: {}",
+            self.parse_sess.span_to_debug_info(mk_sp(start, end)),
         );
 
         self.last_pos = end;
@@ -139,26 +138,22 @@ impl<'a> FmtVisitor<'a> {
         // Get a snippet from the file start to the span's hi without allocating.
         // We need it to determine what precedes the current comment. If the comment
         // follows code on the same line, we won't touch it.
-        let big_span_lo = self.source_map.lookup_char_pos(span.lo()).file.start_pos;
-        let local_begin = self.source_map.lookup_byte_offset(big_span_lo);
-        let local_end = self.source_map.lookup_byte_offset(span.hi());
-        let start_index = local_begin.pos.to_usize();
-        let end_index = local_end.pos.to_usize();
-        let big_snippet = &local_begin.sf.src.as_ref().unwrap()[start_index..end_index];
-
+        let big_span_lo = self.snippet_provider.start_pos();
+        let big_snippet = self.snippet_provider.entire_snippet();
         let big_diff = (span.lo() - big_span_lo).to_usize();
+
         let snippet = self.snippet(span);
 
         debug!("write_snippet `{}`", snippet);
 
-        self.write_snippet_inner(big_snippet, big_diff, snippet, span, process_last_snippet);
+        self.write_snippet_inner(big_snippet, snippet, big_diff, span, process_last_snippet);
     }
 
     fn write_snippet_inner<F>(
         &mut self,
         big_snippet: &str,
-        big_diff: usize,
         old_snippet: &str,
+        big_diff: usize,
         span: Span,
         process_last_snippet: F,
     ) where
@@ -167,9 +162,9 @@ impl<'a> FmtVisitor<'a> {
         // Trim whitespace from the right hand side of each line.
         // Annoyingly, the library functions for splitting by lines etc. are not
         // quite right, so we must do it ourselves.
-        let char_pos = self.source_map.lookup_char_pos(span.lo());
-        let file_name = &char_pos.file.name.clone().into();
-        let mut status = SnippetStatus::new(char_pos.line);
+        let line = self.parse_sess.line_of_byte_pos(span.lo());
+        let file_name = &self.parse_sess.span_to_filename(span);
+        let mut status = SnippetStatus::new(line);
 
         let snippet = &*transform_missing_snippet(self.config, old_snippet);
 
diff --git a/src/modules.rs b/src/modules.rs
index e7a2e21179d..9f8dabbfaf4 100644
--- a/src/modules.rs
+++ b/src/modules.rs
@@ -2,24 +2,25 @@ use std::borrow::Cow;
 use std::collections::BTreeMap;
 use std::path::{Path, PathBuf};
 
-use rustc_errors::PResult;
-use rustc_parse::{new_sub_parser_from_file, parser, DirectoryOwnership};
-use rustc_session::parse::ParseSess;
+use rustc_ast::ast;
+use rustc_ast::visit::Visitor;
 use rustc_span::symbol::{sym, Symbol};
-use rustc_span::{source_map, Span, DUMMY_SP};
-use syntax::ast;
-use syntax::token::TokenKind;
-use syntax::visit::Visitor;
 
 use crate::attr::MetaVisitor;
 use crate::config::FileName;
 use crate::items::is_mod_decl;
+use crate::syntux::parser::{Directory, DirectoryOwnership, ModulePathSuccess, Parser};
+use crate::syntux::session::ParseSess;
 use crate::utils::contains_skip;
 
 mod visitor;
 
 type FileModMap<'ast> = BTreeMap<FileName, Cow<'ast, ast::Mod>>;
 
+lazy_static! {
+    static ref CFG_IF: Symbol = Symbol::intern("cfg_if");
+}
+
 /// Maps each module to the corresponding file.
 pub(crate) struct ModResolver<'ast, 'sess> {
     parse_sess: &'sess ParseSess,
@@ -29,24 +30,9 @@ pub(crate) struct ModResolver<'ast, 'sess> {
 }
 
 #[derive(Clone)]
-struct Directory {
-    path: PathBuf,
-    ownership: DirectoryOwnership,
-}
-
-impl<'a> Directory {
-    fn to_syntax_directory(&'a self) -> rustc_parse::Directory<'a> {
-        rustc_parse::Directory {
-            path: Cow::Borrowed(&self.path),
-            ownership: self.ownership.clone(),
-        }
-    }
-}
-
-#[derive(Clone)]
 enum SubModKind<'a, 'ast> {
     /// `mod foo;`
-    External(PathBuf, DirectoryOwnership),
+    External(PathBuf, DirectoryOwnership, Cow<'ast, ast::Mod>),
     /// `mod foo;` with multiple sources.
     MultiExternal(Vec<(PathBuf, DirectoryOwnership, Cow<'ast, ast::Mod>)>),
     /// `#[path = "..."] mod foo {}`
@@ -78,12 +64,9 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
         mut self,
         krate: &'ast ast::Crate,
     ) -> Result<FileModMap<'ast>, String> {
-        let root_filename = self.parse_sess.source_map().span_to_filename(krate.span);
+        let root_filename = self.parse_sess.span_to_filename(krate.span);
         self.directory.path = match root_filename {
-            source_map::FileName::Real(ref path) => path
-                .parent()
-                .expect("Parent directory should exists")
-                .to_path_buf(),
+            FileName::Real(ref p) => p.parent().unwrap_or(Path::new("")).to_path_buf(),
             _ => PathBuf::new(),
         };
 
@@ -93,14 +76,13 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
         }
 
         self.file_map
-            .insert(root_filename.into(), Cow::Borrowed(&krate.module));
+            .insert(root_filename, Cow::Borrowed(&krate.module));
         Ok(self.file_map)
     }
 
     /// Visit `cfg_if` macro and look for module declarations.
     fn visit_cfg_if(&mut self, item: Cow<'ast, ast::Item>) -> Result<(), String> {
-        let mut visitor =
-            visitor::CfgIfVisitor::new(self.parse_sess, self.directory.to_syntax_directory());
+        let mut visitor = visitor::CfgIfVisitor::new(self.parse_sess);
         visitor.visit_item(&item);
         for module_item in visitor.mods() {
             if let ast::ItemKind::Mod(ref sub_mod) = module_item.item.kind {
@@ -168,7 +150,6 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
             // mod foo;
             // Look for an extern file.
             self.find_external_module(item.ident, &item.attrs, sub_mod)
-                .map(Some)
         } else {
             // An internal module (`mod foo { /* ... */ }`);
             if let Some(path) = find_path_value(&item.attrs) {
@@ -183,15 +164,19 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
     fn insert_sub_mod(
         &mut self,
         sub_mod_kind: SubModKind<'c, 'ast>,
-        sub_mod: Cow<'ast, ast::Mod>,
+        _sub_mod: Cow<'ast, ast::Mod>,
     ) -> Result<(), String> {
         match sub_mod_kind {
-            SubModKind::External(mod_path, _) => {
-                self.file_map.insert(FileName::Real(mod_path), sub_mod);
+            SubModKind::External(mod_path, _, sub_mod) => {
+                self.file_map
+                    .entry(FileName::Real(mod_path))
+                    .or_insert(sub_mod);
             }
             SubModKind::MultiExternal(mods) => {
                 for (mod_path, _, sub_mod) in mods {
-                    self.file_map.insert(FileName::Real(mod_path), sub_mod);
+                    self.file_map
+                        .entry(FileName::Real(mod_path))
+                        .or_insert(sub_mod);
                 }
             }
             _ => (),
@@ -205,7 +190,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
         sub_mod_kind: SubModKind<'c, 'ast>,
     ) -> Result<(), String> {
         match sub_mod_kind {
-            SubModKind::External(mod_path, directory_ownership) => {
+            SubModKind::External(mod_path, directory_ownership, sub_mod) => {
                 let directory = Directory {
                     path: mod_path.parent().unwrap().to_path_buf(),
                     ownership: directory_ownership,
@@ -257,48 +242,87 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
         mod_name: ast::Ident,
         attrs: &[ast::Attribute],
         sub_mod: &Cow<'ast, ast::Mod>,
-    ) -> Result<SubModKind<'c, 'ast>, String> {
-        if let Some(path) = parser::Parser::submod_path_from_attr(attrs, &self.directory.path) {
-            return Ok(SubModKind::External(
-                path,
-                DirectoryOwnership::Owned { relative: None },
-            ));
-        }
-
-        // Look for nested path, like `#[cfg_attr(feature = "foo", path = "bar.rs")]`.
-        let mut mods_outside_ast = self
-            .find_mods_ouside_of_ast(attrs, sub_mod)
-            .unwrap_or(vec![]);
-
+    ) -> Result<Option<SubModKind<'c, 'ast>>, String> {
         let relative = match self.directory.ownership {
             DirectoryOwnership::Owned { relative } => relative,
             DirectoryOwnership::UnownedViaBlock | DirectoryOwnership::UnownedViaMod => None,
         };
-        match parser::Parser::default_submod_path(
-            mod_name,
-            relative,
-            &self.directory.path,
-            self.parse_sess.source_map(),
-        )
-        .result
+        if let Some(path) = Parser::submod_path_from_attr(attrs, &self.directory.path) {
+            if self.parse_sess.is_file_parsed(&path) {
+                return Ok(None);
+            }
+            return match Parser::parse_file_as_module(self.parse_sess, &path, sub_mod.inner) {
+                Some(m) => Ok(Some(SubModKind::External(
+                    path,
+                    DirectoryOwnership::Owned { relative: None },
+                    Cow::Owned(m),
+                ))),
+                None => Err(format!(
+                    "Failed to find module {} in {:?} {:?}",
+                    mod_name, self.directory.path, relative,
+                )),
+            };
+        }
+
+        // Look for nested path, like `#[cfg_attr(feature = "foo", path = "bar.rs")]`.
+        let mut mods_outside_ast = self.find_mods_outside_of_ast(attrs, sub_mod);
+
+        match self
+            .parse_sess
+            .default_submod_path(mod_name, relative, &self.directory.path)
+            .result
         {
-            Ok(parser::ModulePathSuccess {
-                path,
-                directory_ownership,
-                ..
-            }) => Ok(if mods_outside_ast.is_empty() {
-                SubModKind::External(path, directory_ownership)
-            } else {
-                mods_outside_ast.push((path, directory_ownership, sub_mod.clone()));
-                SubModKind::MultiExternal(mods_outside_ast)
-            }),
-            Err(_) if !mods_outside_ast.is_empty() => {
-                Ok(SubModKind::MultiExternal(mods_outside_ast))
+            Ok(ModulePathSuccess {
+                path, ownership, ..
+            }) => {
+                let outside_mods_empty = mods_outside_ast.is_empty();
+                let should_insert = !mods_outside_ast
+                    .iter()
+                    .any(|(outside_path, _, _)| outside_path == &path);
+                if self.parse_sess.is_file_parsed(&path) {
+                    if outside_mods_empty {
+                        return Ok(None);
+                    } else {
+                        if should_insert {
+                            mods_outside_ast.push((path, ownership, sub_mod.clone()));
+                        }
+                        return Ok(Some(SubModKind::MultiExternal(mods_outside_ast)));
+                    }
+                }
+                match Parser::parse_file_as_module(self.parse_sess, &path, sub_mod.inner) {
+                    Some(m) if outside_mods_empty => {
+                        Ok(Some(SubModKind::External(path, ownership, Cow::Owned(m))))
+                    }
+                    Some(m) => {
+                        mods_outside_ast.push((path.clone(), ownership, Cow::Owned(m)));
+                        if should_insert {
+                            mods_outside_ast.push((path, ownership, sub_mod.clone()));
+                        }
+                        Ok(Some(SubModKind::MultiExternal(mods_outside_ast)))
+                    }
+                    None if outside_mods_empty => Err(format!(
+                        "Failed to find module {} in {:?} {:?}",
+                        mod_name, self.directory.path, relative,
+                    )),
+                    None => {
+                        if should_insert {
+                            mods_outside_ast.push((path, ownership, sub_mod.clone()));
+                        }
+                        Ok(Some(SubModKind::MultiExternal(mods_outside_ast)))
+                    }
+                }
+            }
+            Err(mut e) if !mods_outside_ast.is_empty() => {
+                e.cancel();
+                Ok(Some(SubModKind::MultiExternal(mods_outside_ast)))
+            }
+            Err(mut e) => {
+                e.cancel();
+                Err(format!(
+                    "Failed to find module {} in {:?} {:?}",
+                    mod_name, self.directory.path, relative,
+                ))
             }
-            Err(_) => Err(format!(
-                "Failed to find module {} in {:?} {:?}",
-                mod_name, self.directory.path, relative,
-            )),
         }
     }
 
@@ -323,21 +347,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
         }
     }
 
-    fn find_mods_ouside_of_ast(
-        &self,
-        attrs: &[ast::Attribute],
-        sub_mod: &Cow<'ast, ast::Mod>,
-    ) -> Option<Vec<(PathBuf, DirectoryOwnership, Cow<'ast, ast::Mod>)>> {
-        use std::panic::{catch_unwind, AssertUnwindSafe};
-        Some(
-            catch_unwind(AssertUnwindSafe(|| {
-                self.find_mods_ouside_of_ast_inner(attrs, sub_mod)
-            }))
-            .ok()?,
-        )
-    }
-
-    fn find_mods_ouside_of_ast_inner(
+    fn find_mods_outside_of_ast(
         &self,
         attrs: &[ast::Attribute],
         sub_mod: &Cow<'ast, ast::Mod>,
@@ -356,14 +366,8 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
             if !actual_path.exists() {
                 continue;
             }
-            let file_name = rustc_span::FileName::Real(actual_path.clone());
-            if self
-                .parse_sess
-                .source_map()
-                .get_source_file(&file_name)
-                .is_some()
-            {
-                // If the specfied file is already parsed, then we just use that.
+            if self.parse_sess.is_file_parsed(&actual_path) {
+                // If the specified file is already parsed, then we just use that.
                 result.push((
                     actual_path,
                     DirectoryOwnership::Owned { relative: None },
@@ -371,32 +375,12 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
                 ));
                 continue;
             }
-            let mut parser = new_sub_parser_from_file(
-                self.parse_sess,
-                &actual_path,
-                self.directory.ownership,
-                None,
-                DUMMY_SP,
-            );
-            parser.cfg_mods = false;
-            let lo = parser.token.span;
-            // FIXME(topecongiro) Format inner attributes (#3606).
-            let _mod_attrs = match parse_inner_attributes(&mut parser) {
-                Ok(attrs) => attrs,
-                Err(mut e) => {
-                    e.cancel();
-                    parser.sess.span_diagnostic.reset_err_count();
-                    continue;
-                }
-            };
-            let m = match parse_mod_items(&mut parser, lo) {
-                Ok(m) => m,
-                Err(mut e) => {
-                    e.cancel();
-                    parser.sess.span_diagnostic.reset_err_count();
-                    continue;
-                }
+            let m = match Parser::parse_file_as_module(self.parse_sess, &actual_path, sub_mod.inner)
+            {
+                Some(m) => m,
+                None => continue,
             };
+
             result.push((
                 actual_path,
                 DirectoryOwnership::Owned { relative: None },
@@ -422,67 +406,11 @@ fn find_path_value(attrs: &[ast::Attribute]) -> Option<Symbol> {
     attrs.iter().flat_map(path_value).next()
 }
 
-// FIXME(topecongiro) Use the method from libsyntax[1] once it become public.
-//
-// [1] https://github.com/rust-lang/rust/blob/master/src/libsyntax/parse/attr.rs
-fn parse_inner_attributes<'a>(parser: &mut parser::Parser<'a>) -> PResult<'a, Vec<ast::Attribute>> {
-    let mut attrs: Vec<ast::Attribute> = vec![];
-    loop {
-        match parser.token.kind {
-            TokenKind::Pound => {
-                // Don't even try to parse if it's not an inner attribute.
-                if !parser.look_ahead(1, |t| t == &TokenKind::Not) {
-                    break;
-                }
-
-                let attr = parser.parse_attribute(true)?;
-                assert_eq!(attr.style, ast::AttrStyle::Inner);
-                attrs.push(attr);
-            }
-            TokenKind::DocComment(s) => {
-                // we need to get the position of this token before we bump.
-                let attr = syntax::attr::mk_doc_comment(
-                    syntax::util::comments::doc_comment_style(&s.as_str()),
-                    s,
-                    parser.token.span,
-                );
-                if attr.style == ast::AttrStyle::Inner {
-                    attrs.push(attr);
-                    parser.bump();
-                } else {
-                    break;
-                }
-            }
-            _ => break,
-        }
-    }
-    Ok(attrs)
-}
-
-fn parse_mod_items<'a>(parser: &mut parser::Parser<'a>, inner_lo: Span) -> PResult<'a, ast::Mod> {
-    let mut items = vec![];
-    while let Some(item) = parser.parse_item()? {
-        items.push(item);
-    }
-
-    let hi = if parser.token.span.is_dummy() {
-        inner_lo
-    } else {
-        parser.prev_span
-    };
-
-    Ok(ast::Mod {
-        inner: inner_lo.to(hi),
-        items,
-        inline: false,
-    })
-}
-
 fn is_cfg_if(item: &ast::Item) -> bool {
     match item.kind {
-        ast::ItemKind::Mac(ref mac) => {
+        ast::ItemKind::MacCall(ref mac) => {
             if let Some(first_segment) = mac.path.segments.first() {
-                if first_segment.ident.name == Symbol::intern("cfg_if") {
+                if first_segment.ident.name == *CFG_IF {
                     return true;
                 }
             }
diff --git a/src/modules/visitor.rs b/src/modules/visitor.rs
index 4ef1daf7475..942e70d0e88 100644
--- a/src/modules/visitor.rs
+++ b/src/modules/visitor.rs
@@ -1,11 +1,10 @@
-use rustc_parse::{stream_to_parser_with_base_dir, Directory};
-use rustc_session::parse::ParseSess;
-use rustc_span::{symbol::kw, Symbol};
-use syntax::ast;
-use syntax::token::{DelimToken, TokenKind};
-use syntax::visit::Visitor;
+use rustc_ast::ast;
+use rustc_ast::visit::Visitor;
+use rustc_span::Symbol;
 
 use crate::attr::MetaVisitor;
+use crate::syntux::parser::Parser;
+use crate::syntux::session::ParseSess;
 
 pub(crate) struct ModItem {
     pub(crate) item: ast::Item,
@@ -15,15 +14,13 @@ pub(crate) struct ModItem {
 pub(crate) struct CfgIfVisitor<'a> {
     parse_sess: &'a ParseSess,
     mods: Vec<ModItem>,
-    base_dir: Directory<'a>,
 }
 
 impl<'a> CfgIfVisitor<'a> {
-    pub(crate) fn new(parse_sess: &'a ParseSess, base_dir: Directory<'a>) -> CfgIfVisitor<'a> {
+    pub(crate) fn new(parse_sess: &'a ParseSess) -> CfgIfVisitor<'a> {
         CfgIfVisitor {
             mods: vec![],
             parse_sess,
-            base_dir,
         }
     }
 
@@ -33,7 +30,7 @@ impl<'a> CfgIfVisitor<'a> {
 }
 
 impl<'a, 'ast: 'a> Visitor<'ast> for CfgIfVisitor<'a> {
-    fn visit_mac(&mut self, mac: &'ast ast::Mac) {
+    fn visit_mac(&mut self, mac: &'ast ast::MacCall) {
         match self.visit_mac_inner(mac) {
             Ok(()) => (),
             Err(e) => debug!("{}", e),
@@ -42,7 +39,7 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CfgIfVisitor<'a> {
 }
 
 impl<'a, 'ast: 'a> CfgIfVisitor<'a> {
-    fn visit_mac_inner(&mut self, mac: &'ast ast::Mac) -> Result<(), &'static str> {
+    fn visit_mac_inner(&mut self, mac: &'ast ast::MacCall) -> Result<(), &'static str> {
         // Support both:
         // ```
         // extern crate cfg_if;
@@ -65,59 +62,9 @@ impl<'a, 'ast: 'a> CfgIfVisitor<'a> {
             }
         };
 
-        let ts = mac.args.inner_tokens();
-        let mut parser =
-            stream_to_parser_with_base_dir(self.parse_sess, ts.clone(), self.base_dir.clone());
-        parser.cfg_mods = false;
-        let mut process_if_cfg = true;
-
-        while parser.token.kind != TokenKind::Eof {
-            if process_if_cfg {
-                if !parser.eat_keyword(kw::If) {
-                    return Err("Expected `if`");
-                }
-                parser
-                    .parse_attribute(false)
-                    .map_err(|_| "Failed to parse attributes")?;
-            }
-
-            if !parser.eat(&TokenKind::OpenDelim(DelimToken::Brace)) {
-                return Err("Expected an opening brace");
-            }
-
-            while parser.token != TokenKind::CloseDelim(DelimToken::Brace)
-                && parser.token.kind != TokenKind::Eof
-            {
-                let item = match parser.parse_item() {
-                    Ok(Some(item_ptr)) => item_ptr.into_inner(),
-                    Ok(None) => continue,
-                    Err(mut err) => {
-                        err.cancel();
-                        parser.sess.span_diagnostic.reset_err_count();
-                        return Err(
-                            "Expected item inside cfg_if block, but failed to parse it as an item",
-                        );
-                    }
-                };
-                if let ast::ItemKind::Mod(..) = item.kind {
-                    self.mods.push(ModItem { item });
-                }
-            }
-
-            if !parser.eat(&TokenKind::CloseDelim(DelimToken::Brace)) {
-                return Err("Expected a closing brace");
-            }
-
-            if parser.eat(&TokenKind::Eof) {
-                break;
-            }
-
-            if !parser.eat_keyword(kw::Else) {
-                return Err("Expected `else`");
-            }
-
-            process_if_cfg = parser.token.is_keyword(kw::If);
-        }
+        let items = Parser::parse_cfg_if(self.parse_sess, mac)?;
+        self.mods
+            .append(&mut items.into_iter().map(|item| ModItem { item }).collect());
 
         Ok(())
     }
diff --git a/src/overflow.rs b/src/overflow.rs
index 0ef1db20fa1..566f0e36639 100644
--- a/src/overflow.rs
+++ b/src/overflow.rs
@@ -3,9 +3,9 @@
 use std::cmp::min;
 
 use itertools::Itertools;
+use rustc_ast::token::DelimToken;
+use rustc_ast::{ast, ptr};
 use rustc_span::Span;
-use syntax::token::DelimToken;
-use syntax::{ast, ptr};
 
 use crate::closures;
 use crate::config::lists::*;
diff --git a/src/pairs.rs b/src/pairs.rs
index 45132c1f9f6..0f3d5e8f878 100644
--- a/src/pairs.rs
+++ b/src/pairs.rs
@@ -1,4 +1,4 @@
-use syntax::ast;
+use rustc_ast::ast;
 
 use crate::config::lists::*;
 use crate::config::IndentStyle;
diff --git a/src/patterns.rs b/src/patterns.rs
index 1ef3bd5337b..78292620232 100644
--- a/src/patterns.rs
+++ b/src/patterns.rs
@@ -1,6 +1,6 @@
+use rustc_ast::ast::{self, BindingMode, FieldPat, Pat, PatKind, RangeEnd, RangeSyntax};
+use rustc_ast::ptr;
 use rustc_span::{BytePos, Span};
-use syntax::ast::{self, BindingMode, FieldPat, Pat, PatKind, RangeEnd, RangeSyntax};
-use syntax::ptr;
 
 use crate::comment::{combine_strs_with_missing_comments, FindUncommented};
 use crate::config::lists::*;
@@ -40,7 +40,7 @@ fn is_short_pattern_inner(pat: &ast::Pat) -> bool {
         ast::PatKind::Rest | ast::PatKind::Wild | ast::PatKind::Lit(_) => true,
         ast::PatKind::Ident(_, _, ref pat) => pat.is_none(),
         ast::PatKind::Struct(..)
-        | ast::PatKind::Mac(..)
+        | ast::PatKind::MacCall(..)
         | ast::PatKind::Slice(..)
         | ast::PatKind::Path(..)
         | ast::PatKind::Range(..) => false,
@@ -231,7 +231,9 @@ impl Rewrite for Pat {
             PatKind::Struct(ref path, ref fields, ellipsis) => {
                 rewrite_struct_pat(path, fields, ellipsis, self.span, context, shape)
             }
-            PatKind::Mac(ref mac) => rewrite_macro(mac, None, context, shape, MacroPosition::Pat),
+            PatKind::MacCall(ref mac) => {
+                rewrite_macro(mac, None, context, shape, MacroPosition::Pat)
+            }
             PatKind::Paren(ref pat) => pat
                 .rewrite(context, shape.offset_left(1)?.sub_width(1)?)
                 .map(|inner_pat| format!("({})", inner_pat)),
diff --git a/src/reorder.rs b/src/reorder.rs
index 4b607812c00..3b9f2475acc 100644
--- a/src/reorder.rs
+++ b/src/reorder.rs
@@ -8,8 +8,8 @@
 
 use std::cmp::{Ord, Ordering};
 
+use rustc_ast::{ast, attr};
 use rustc_span::{symbol::sym, Span};
-use syntax::{ast, attr};
 
 use crate::config::Config;
 use crate::imports::{merge_use_trees, UseTree};
@@ -207,13 +207,13 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
         item_kind: ReorderableItemKind,
         in_group: bool,
     ) -> usize {
-        let mut last = self.source_map.lookup_line_range(items[0].span());
+        let mut last = self.parse_sess.lookup_line_range(items[0].span());
         let item_length = items
             .iter()
             .take_while(|ppi| {
                 item_kind.is_same_item_kind(&***ppi)
                     && (!in_group || {
-                        let current = self.source_map.lookup_line_range(ppi.span());
+                        let current = self.parse_sess.lookup_line_range(ppi.span());
                         let in_same_group = current.lo < last.hi + 2;
                         last = current;
                         in_same_group
diff --git a/src/rewrite.rs b/src/rewrite.rs
index fbae4bc7122..86b2e9ded1c 100644
--- a/src/rewrite.rs
+++ b/src/rewrite.rs
@@ -3,13 +3,13 @@
 use std::cell::{Cell, RefCell};
 use std::rc::Rc;
 
-use rustc_session::parse::ParseSess;
-use rustc_span::{source_map::SourceMap, Span};
-use syntax::ptr;
+use rustc_ast::ptr;
+use rustc_span::Span;
 
 use crate::config::{Config, IndentStyle};
 use crate::shape::Shape;
 use crate::skip::SkipContext;
+use crate::syntux::session::ParseSess;
 use crate::visitor::SnippetProvider;
 use crate::FormatReport;
 
@@ -26,8 +26,7 @@ impl<T: Rewrite> Rewrite for ptr::P<T> {
 
 #[derive(Clone)]
 pub(crate) struct RewriteContext<'a> {
-    pub(crate) parse_session: &'a ParseSess,
-    pub(crate) source_map: &'a SourceMap,
+    pub(crate) parse_sess: &'a ParseSess,
     pub(crate) config: &'a Config,
     pub(crate) inside_macro: Rc<Cell<bool>>,
     // Force block indent style even if we are using visual indent style.
@@ -37,7 +36,7 @@ pub(crate) struct RewriteContext<'a> {
     pub(crate) is_if_else_block: Cell<bool>,
     // When rewriting chain, veto going multi line except the last element
     pub(crate) force_one_line_chain: Cell<bool>,
-    pub(crate) snippet_provider: &'a SnippetProvider<'a>,
+    pub(crate) snippet_provider: &'a SnippetProvider,
     // Used for `format_snippet`
     pub(crate) macro_rewrite_failure: Cell<bool>,
     pub(crate) report: FormatReport,
diff --git a/src/skip.rs b/src/skip.rs
index 4972eb8c778..fd48e67ee73 100644
--- a/src/skip.rs
+++ b/src/skip.rs
@@ -1,7 +1,7 @@
 //! Module that contains skip related stuffs.
 
+use rustc_ast::ast;
 use rustc_ast_pretty::pprust;
-use syntax::ast;
 
 /// Take care of skip name stack. You can update it by attributes slice or
 /// by other context. Query this context to know if you need skip a block.
@@ -56,7 +56,7 @@ fn get_skip_names(kind: &str, attrs: &[ast::Attribute]) -> Vec<String> {
     let mut skip_names = vec![];
     let path = format!("{}::{}::{}", RUSTFMT, SKIP, kind);
     for attr in attrs {
-        // syntax::ast::Path is implemented partialEq
+        // rustc_ast::ast::Path is implemented partialEq
         // but it is designed for segments.len() == 1
         if let ast::AttrKind::Normal(attr_item) = &attr.kind {
             if pprust::path_to_string(&attr_item.path) != path {
diff --git a/src/source_file.rs b/src/source_file.rs
index 4cb894e55b8..4f02d8224e2 100644
--- a/src/source_file.rs
+++ b/src/source_file.rs
@@ -2,10 +2,9 @@ use std::fs;
 use std::io::{self, Write};
 use std::path::Path;
 
-use rustc_span::source_map::SourceMap;
-
 use crate::config::FileName;
 use crate::emitter::{self, Emitter};
+use crate::syntux::session::ParseSess;
 use crate::NewlineStyle;
 
 #[cfg(test)]
@@ -14,6 +13,7 @@ use crate::config::Config;
 use crate::create_emitter;
 #[cfg(test)]
 use crate::formatting::FileRecord;
+use std::rc::Rc;
 
 // Append a newline to the end of each file.
 pub(crate) fn append_newline(s: &mut String) {
@@ -48,7 +48,7 @@ where
 }
 
 pub(crate) fn write_file<T>(
-    source_map: Option<&SourceMap>,
+    parse_sess: Option<&ParseSess>,
     filename: &FileName,
     formatted_text: &str,
     out: &mut T,
@@ -84,20 +84,17 @@ where
     // source map instead of hitting the file system. This also supports getting
     // original text for `FileName::Stdin`.
     let original_text = if newline_style != NewlineStyle::Auto && *filename != FileName::Stdin {
-        fs::read_to_string(ensure_real_path(filename))?
+        Rc::new(fs::read_to_string(ensure_real_path(filename))?)
     } else {
-        match source_map
-            .and_then(|x| x.get_source_file(&filename.into()))
-            .and_then(|x| x.src.as_ref().map(ToString::to_string))
-        {
+        match parse_sess.and_then(|sess| sess.get_original_snippet(filename)) {
             Some(ori) => ori,
-            None => fs::read_to_string(ensure_real_path(filename))?,
+            None => Rc::new(fs::read_to_string(ensure_real_path(filename))?),
         }
     };
 
     let formatted_file = emitter::FormattedFile {
         filename,
-        original_text: &original_text,
+        original_text: original_text.as_str(),
         formatted_text,
     };
 
diff --git a/src/source_map.rs b/src/source_map.rs
index c3a549d3b84..76e0d24cf1e 100644
--- a/src/source_map.rs
+++ b/src/source_map.rs
@@ -1,11 +1,10 @@
 //! This module contains utilities that work with the `SourceMap` from `libsyntax`/`syntex_syntax`.
 //! This includes extension traits and methods for looking up spans and line ranges for AST nodes.
 
-use rustc_span::{source_map::SourceMap, BytePos, Span};
+use rustc_span::{BytePos, Span};
 
 use crate::comment::FindUncommented;
 use crate::config::file_lines::LineRange;
-use crate::utils::starts_with_newline;
 use crate::visitor::SnippetProvider;
 
 pub(crate) trait SpanUtils {
@@ -26,7 +25,7 @@ pub(crate) trait LineRangeUtils {
     fn lookup_line_range(&self, span: Span) -> LineRange;
 }
 
-impl<'a> SpanUtils for SnippetProvider<'a> {
+impl SpanUtils for SnippetProvider {
     fn span_after(&self, original: Span, needle: &str) -> BytePos {
         self.opt_span_after(original, needle).unwrap_or_else(|| {
             panic!(
@@ -81,27 +80,3 @@ impl<'a> SpanUtils for SnippetProvider<'a> {
         Some(original.lo() + BytePos(offset as u32))
     }
 }
-
-impl LineRangeUtils for SourceMap {
-    fn lookup_line_range(&self, span: Span) -> LineRange {
-        let snippet = self.span_to_snippet(span).unwrap_or_default();
-        let lo = self.lookup_line(span.lo()).unwrap();
-        let hi = self.lookup_line(span.hi()).unwrap();
-
-        debug_assert_eq!(
-            lo.sf.name, hi.sf.name,
-            "span crossed file boundary: lo: {:?}, hi: {:?}",
-            lo, hi
-        );
-
-        // in case the span starts with a newline, the line range is off by 1 without the
-        // adjustment below
-        let offset = 1 + if starts_with_newline(&snippet) { 1 } else { 0 };
-        // Line numbers start at 1
-        LineRange {
-            file: lo.sf.clone(),
-            lo: lo.line + offset,
-            hi: hi.line + offset,
-        }
-    }
-}
diff --git a/src/spanned.rs b/src/spanned.rs
index b2a70dd5cec..60a350524fa 100644
--- a/src/spanned.rs
+++ b/src/spanned.rs
@@ -1,7 +1,7 @@
 use std::cmp::max;
 
+use rustc_ast::{ast, ptr};
 use rustc_span::{source_map, Span};
-use syntax::{ast, ptr};
 
 use crate::macros::MacroArg;
 use crate::utils::{mk_sp, outer_attributes};
@@ -66,7 +66,7 @@ impl Spanned for ast::Stmt {
             ast::StmtKind::Expr(ref expr) | ast::StmtKind::Semi(ref expr) => {
                 mk_sp(expr.span().lo(), self.span.hi())
             }
-            ast::StmtKind::Mac(ref mac) => {
+            ast::StmtKind::MacCall(ref mac) => {
                 let (_, _, ref attrs) = **mac;
                 if attrs.is_empty() {
                     self.span
@@ -74,6 +74,7 @@ impl Spanned for ast::Stmt {
                     mk_sp(attrs[0].span.lo(), self.span.hi())
                 }
             }
+            ast::StmtKind::Empty => self.span,
         }
     }
 }
@@ -151,11 +152,11 @@ impl Spanned for ast::WherePredicate {
     }
 }
 
-impl Spanned for ast::FunctionRetTy {
+impl Spanned for ast::FnRetTy {
     fn span(&self) -> Span {
         match *self {
-            ast::FunctionRetTy::Default(span) => span,
-            ast::FunctionRetTy::Ty(ref ty) => ty.span,
+            ast::FnRetTy::Default(span) => span,
+            ast::FnRetTy::Ty(ref ty) => ty.span,
         }
     }
 }
diff --git a/src/stmt.rs b/src/stmt.rs
index df22a5dfd02..807cd9e5fad 100644
--- a/src/stmt.rs
+++ b/src/stmt.rs
@@ -1,5 +1,5 @@
+use rustc_ast::ast;
 use rustc_span::Span;
-use syntax::ast;
 
 use crate::comment::recover_comment_removed;
 use crate::config::Version;
@@ -106,7 +106,7 @@ fn format_stmt(
             let shape = shape.sub_width(suffix.len())?;
             format_expr(ex, expr_type, context, shape).map(|s| s + suffix)
         }
-        ast::StmtKind::Mac(..) | ast::StmtKind::Item(..) => None,
+        ast::StmtKind::MacCall(..) | ast::StmtKind::Item(..) | ast::StmtKind::Empty => None,
     };
     result.and_then(|res| recover_comment_removed(res, stmt.span(), context))
 }
diff --git a/src/syntux.rs b/src/syntux.rs
new file mode 100644
index 00000000000..845576bd8d8
--- /dev/null
+++ b/src/syntux.rs
@@ -0,0 +1,4 @@
+//! This module defines a thin abstract layer on top of the rustc's parser and syntax libraries.
+
+pub(crate) mod parser;
+pub(crate) mod session;
diff --git a/src/syntux/parser.rs b/src/syntux/parser.rs
new file mode 100644
index 00000000000..04a6f7577a0
--- /dev/null
+++ b/src/syntux/parser.rs
@@ -0,0 +1,312 @@
+use std::panic::{catch_unwind, AssertUnwindSafe};
+use std::path::{Path, PathBuf};
+
+use rustc_ast::ast;
+use rustc_ast::token::{DelimToken, TokenKind};
+use rustc_errors::{Diagnostic, PResult};
+use rustc_parse::{new_parser_from_file, parser::Parser as RawParser};
+use rustc_span::{symbol::kw, Span};
+
+use crate::syntux::session::ParseSess;
+use crate::{Config, Input};
+
+pub(crate) type DirectoryOwnership = rustc_expand::module::DirectoryOwnership;
+pub(crate) type ModulePathSuccess = rustc_expand::module::ModulePathSuccess;
+
+#[derive(Clone)]
+pub(crate) struct Directory {
+    pub(crate) path: PathBuf,
+    pub(crate) ownership: DirectoryOwnership,
+}
+
+/// A parser for Rust source code.
+pub(crate) struct Parser<'a> {
+    parser: RawParser<'a>,
+    sess: &'a ParseSess,
+}
+
+/// A builder for the `Parser`.
+#[derive(Default)]
+pub(crate) struct ParserBuilder<'a> {
+    config: Option<&'a Config>,
+    sess: Option<&'a ParseSess>,
+    input: Option<Input>,
+    directory_ownership: Option<DirectoryOwnership>,
+}
+
+impl<'a> ParserBuilder<'a> {
+    pub(crate) fn input(mut self, input: Input) -> ParserBuilder<'a> {
+        self.input = Some(input);
+        self
+    }
+
+    pub(crate) fn sess(mut self, sess: &'a ParseSess) -> ParserBuilder<'a> {
+        self.sess = Some(sess);
+        self
+    }
+
+    pub(crate) fn config(mut self, config: &'a Config) -> ParserBuilder<'a> {
+        self.config = Some(config);
+        self
+    }
+
+    pub(crate) fn directory_ownership(
+        mut self,
+        directory_ownership: Option<DirectoryOwnership>,
+    ) -> ParserBuilder<'a> {
+        self.directory_ownership = directory_ownership;
+        self
+    }
+
+    pub(crate) fn build(self) -> Result<Parser<'a>, ParserError> {
+        let sess = self.sess.ok_or(ParserError::NoParseSess)?;
+        let input = self.input.ok_or(ParserError::NoInput)?;
+
+        let parser = match Self::parser(sess.inner(), input) {
+            Ok(p) => p,
+            Err(db) => {
+                sess.emit_diagnostics(db);
+                return Err(ParserError::ParserCreationError);
+            }
+        };
+
+        Ok(Parser { parser, sess })
+    }
+
+    fn parser(
+        sess: &'a rustc_session::parse::ParseSess,
+        input: Input,
+    ) -> Result<rustc_parse::parser::Parser<'a>, Vec<Diagnostic>> {
+        match input {
+            Input::File(ref file) => Ok(new_parser_from_file(sess, file, None)),
+            Input::Text(text) => rustc_parse::maybe_new_parser_from_source_str(
+                sess,
+                rustc_span::FileName::Custom("stdin".to_owned()),
+                text,
+            ),
+        }
+    }
+}
+
+#[derive(Debug, PartialEq)]
+pub(crate) enum ParserError {
+    NoParseSess,
+    NoInput,
+    ParserCreationError,
+    ParseError,
+    ParsePanicError,
+}
+
+impl<'a> Parser<'a> {
+    pub(crate) fn submod_path_from_attr(attrs: &[ast::Attribute], path: &Path) -> Option<PathBuf> {
+        rustc_expand::module::submod_path_from_attr(attrs, path)
+    }
+
+    // FIXME(topecongiro) Use the method from libsyntax[1] once it become public.
+    //
+    // [1] https://github.com/rust-lang/rust/blob/master/src/libsyntax/parse/attr.rs
+    fn parse_inner_attrs(parser: &mut RawParser<'a>) -> PResult<'a, Vec<ast::Attribute>> {
+        let mut attrs: Vec<ast::Attribute> = vec![];
+        loop {
+            match parser.token.kind {
+                TokenKind::Pound => {
+                    // Don't even try to parse if it's not an inner attribute.
+                    if !parser.look_ahead(1, |t| t == &TokenKind::Not) {
+                        break;
+                    }
+
+                    let attr = parser.parse_attribute(true)?;
+                    assert_eq!(attr.style, ast::AttrStyle::Inner);
+                    attrs.push(attr);
+                }
+                TokenKind::DocComment(s) => {
+                    // we need to get the position of this token before we bump.
+                    let attr = rustc_ast::attr::mk_doc_comment(
+                        rustc_ast::util::comments::doc_comment_style(&s.as_str()),
+                        s,
+                        parser.token.span,
+                    );
+                    if attr.style == ast::AttrStyle::Inner {
+                        attrs.push(attr);
+                        parser.bump();
+                    } else {
+                        break;
+                    }
+                }
+                _ => break,
+            }
+        }
+        Ok(attrs)
+    }
+
+    fn parse_mod_items(parser: &mut RawParser<'a>, span: Span) -> PResult<'a, ast::Mod> {
+        let mut items = vec![];
+        while let Some(item) = parser.parse_item()? {
+            items.push(item);
+        }
+
+        // Handle extern mods that are empty files/files with only comments.
+        if items.is_empty() {
+            parser.parse_mod(&TokenKind::Eof)?;
+        }
+
+        let hi = if parser.token.span.is_dummy() {
+            span
+        } else {
+            parser.prev_token.span
+        };
+
+        Ok(ast::Mod {
+            inner: span.to(hi),
+            items,
+            inline: false,
+        })
+    }
+
+    pub(crate) fn parse_file_as_module(
+        sess: &'a ParseSess,
+        path: &Path,
+        span: Span,
+    ) -> Option<ast::Mod> {
+        let result = catch_unwind(AssertUnwindSafe(|| {
+            let mut parser = new_parser_from_file(sess.inner(), &path, Some(span));
+
+            let lo = parser.token.span;
+            // FIXME(topecongiro) Format inner attributes (#3606).
+            match Parser::parse_inner_attrs(&mut parser) {
+                Ok(_attrs) => (),
+                Err(mut e) => {
+                    e.cancel();
+                    sess.reset_errors();
+                    return None;
+                }
+            }
+
+            match Parser::parse_mod_items(&mut parser, lo) {
+                Ok(m) => Some(m),
+                Err(mut db) => {
+                    db.cancel();
+                    sess.reset_errors();
+                    None
+                }
+            }
+        }));
+        match result {
+            Ok(Some(m)) => Some(m),
+            _ => None,
+        }
+    }
+
+    pub(crate) fn parse_crate(
+        config: &'a Config,
+        input: Input,
+        directory_ownership: Option<DirectoryOwnership>,
+        sess: &'a ParseSess,
+    ) -> Result<ast::Crate, ParserError> {
+        let mut parser = ParserBuilder::default()
+            .config(config)
+            .input(input)
+            .directory_ownership(directory_ownership)
+            .sess(sess)
+            .build()?;
+
+        parser.parse_crate_inner()
+    }
+
+    fn parse_crate_inner(&mut self) -> Result<ast::Crate, ParserError> {
+        let mut parser = AssertUnwindSafe(&mut self.parser);
+
+        match catch_unwind(move || parser.parse_crate_mod()) {
+            Ok(Ok(krate)) => {
+                if !self.sess.has_errors() {
+                    return Ok(krate);
+                }
+
+                if self.sess.can_reset_errors() {
+                    self.sess.reset_errors();
+                    return Ok(krate);
+                }
+
+                Err(ParserError::ParseError)
+            }
+            Ok(Err(mut db)) => {
+                db.emit();
+                Err(ParserError::ParseError)
+            }
+            Err(_) => Err(ParserError::ParsePanicError),
+        }
+    }
+
+    pub(crate) fn parse_cfg_if(
+        sess: &'a ParseSess,
+        mac: &'a ast::MacCall,
+    ) -> Result<Vec<ast::Item>, &'static str> {
+        match catch_unwind(AssertUnwindSafe(|| Parser::parse_cfg_if_inner(sess, mac))) {
+            Ok(Ok(items)) => Ok(items),
+            Ok(err @ Err(_)) => err,
+            Err(..) => Err("failed to parse cfg_if!"),
+        }
+    }
+
+    fn parse_cfg_if_inner(
+        sess: &'a ParseSess,
+        mac: &'a ast::MacCall,
+    ) -> Result<Vec<ast::Item>, &'static str> {
+        let token_stream = mac.args.inner_tokens();
+        let mut parser =
+            rustc_parse::stream_to_parser(sess.inner(), token_stream.clone(), Some(""));
+
+        let mut items = vec![];
+        let mut process_if_cfg = true;
+
+        while parser.token.kind != TokenKind::Eof {
+            if process_if_cfg {
+                if !parser.eat_keyword(kw::If) {
+                    return Err("Expected `if`");
+                }
+                parser
+                    .parse_attribute(false)
+                    .map_err(|_| "Failed to parse attributes")?;
+            }
+
+            if !parser.eat(&TokenKind::OpenDelim(DelimToken::Brace)) {
+                return Err("Expected an opening brace");
+            }
+
+            while parser.token != TokenKind::CloseDelim(DelimToken::Brace)
+                && parser.token.kind != TokenKind::Eof
+            {
+                let item = match parser.parse_item() {
+                    Ok(Some(item_ptr)) => item_ptr.into_inner(),
+                    Ok(None) => continue,
+                    Err(mut err) => {
+                        err.cancel();
+                        parser.sess.span_diagnostic.reset_err_count();
+                        return Err(
+                            "Expected item inside cfg_if block, but failed to parse it as an item",
+                        );
+                    }
+                };
+                if let ast::ItemKind::Mod(..) = item.kind {
+                    items.push(item);
+                }
+            }
+
+            if !parser.eat(&TokenKind::CloseDelim(DelimToken::Brace)) {
+                return Err("Expected a closing brace");
+            }
+
+            if parser.eat(&TokenKind::Eof) {
+                break;
+            }
+
+            if !parser.eat_keyword(kw::Else) {
+                return Err("Expected `else`");
+            }
+
+            process_if_cfg = parser.token.is_keyword(kw::If);
+        }
+
+        Ok(items)
+    }
+}
diff --git a/src/syntux/session.rs b/src/syntux/session.rs
new file mode 100644
index 00000000000..da8741c84e5
--- /dev/null
+++ b/src/syntux/session.rs
@@ -0,0 +1,441 @@
+use std::cell::RefCell;
+use std::path::Path;
+use std::rc::Rc;
+
+use rustc_ast::ast;
+use rustc_data_structures::sync::{Lrc, Send};
+use rustc_errors::emitter::{Emitter, EmitterWriter};
+use rustc_errors::{ColorConfig, Diagnostic, Handler, Level as DiagnosticLevel};
+use rustc_session::parse::ParseSess as RawParseSess;
+use rustc_span::{
+    source_map::{FilePathMapping, SourceMap},
+    BytePos, Span,
+};
+
+use crate::config::file_lines::LineRange;
+use crate::ignore_path::IgnorePathSet;
+use crate::source_map::LineRangeUtils;
+use crate::utils::starts_with_newline;
+use crate::visitor::SnippetProvider;
+use crate::{Config, ErrorKind, FileName};
+
+/// ParseSess holds structs necessary for constructing a parser.
+pub(crate) struct ParseSess {
+    parse_sess: RawParseSess,
+    ignore_path_set: Rc<IgnorePathSet>,
+    can_reset_errors: Rc<RefCell<bool>>,
+}
+
+/// Emitter which discards every error.
+struct SilentEmitter;
+
+impl Emitter for SilentEmitter {
+    fn source_map(&self) -> Option<&Lrc<SourceMap>> {
+        None
+    }
+    fn emit_diagnostic(&mut self, _db: &Diagnostic) {}
+}
+
+fn silent_emitter() -> Box<dyn Emitter + Send> {
+    Box::new(SilentEmitter {})
+}
+
+/// Emit errors against every files expect ones specified in the `ignore_path_set`.
+struct SilentOnIgnoredFilesEmitter {
+    ignore_path_set: Rc<IgnorePathSet>,
+    source_map: Rc<SourceMap>,
+    emitter: Box<dyn Emitter + Send>,
+    has_non_ignorable_parser_errors: bool,
+    can_reset: Rc<RefCell<bool>>,
+}
+
+impl SilentOnIgnoredFilesEmitter {
+    fn handle_non_ignoreable_error(&mut self, db: &Diagnostic) {
+        self.has_non_ignorable_parser_errors = true;
+        *self.can_reset.borrow_mut() = false;
+        self.emitter.emit_diagnostic(db);
+    }
+}
+
+impl Emitter for SilentOnIgnoredFilesEmitter {
+    fn source_map(&self) -> Option<&Lrc<SourceMap>> {
+        None
+    }
+    fn emit_diagnostic(&mut self, db: &Diagnostic) {
+        if db.level == DiagnosticLevel::Fatal {
+            return self.handle_non_ignoreable_error(db);
+        }
+        if let Some(primary_span) = &db.span.primary_span() {
+            let file_name = self.source_map.span_to_filename(*primary_span);
+            if let rustc_span::FileName::Real(ref path) = file_name {
+                if self
+                    .ignore_path_set
+                    .is_match(&FileName::Real(path.to_path_buf()))
+                {
+                    if !self.has_non_ignorable_parser_errors {
+                        *self.can_reset.borrow_mut() = true;
+                    }
+                    return;
+                }
+            };
+        }
+        self.handle_non_ignoreable_error(db);
+    }
+}
+
+fn default_handler(
+    source_map: Rc<SourceMap>,
+    ignore_path_set: Rc<IgnorePathSet>,
+    can_reset: Rc<RefCell<bool>>,
+    hide_parse_errors: bool,
+) -> Handler {
+    let supports_color = term::stderr().map_or(false, |term| term.supports_color());
+    let color_cfg = if supports_color {
+        ColorConfig::Auto
+    } else {
+        ColorConfig::Never
+    };
+
+    let emitter = if hide_parse_errors {
+        silent_emitter()
+    } else {
+        Box::new(EmitterWriter::stderr(
+            color_cfg,
+            Some(source_map.clone()),
+            false,
+            false,
+            None,
+            false,
+        ))
+    };
+    Handler::with_emitter(
+        true,
+        None,
+        Box::new(SilentOnIgnoredFilesEmitter {
+            has_non_ignorable_parser_errors: false,
+            source_map,
+            emitter,
+            ignore_path_set,
+            can_reset,
+        }),
+    )
+}
+
+impl ParseSess {
+    pub(crate) fn new(config: &Config) -> Result<ParseSess, ErrorKind> {
+        let ignore_path_set = match IgnorePathSet::from_ignore_list(&config.ignore()) {
+            Ok(ignore_path_set) => Rc::new(ignore_path_set),
+            Err(e) => return Err(ErrorKind::InvalidGlobPattern(e)),
+        };
+        let source_map = Rc::new(SourceMap::new(FilePathMapping::empty()));
+        let can_reset_errors = Rc::new(RefCell::new(false));
+
+        let handler = default_handler(
+            Rc::clone(&source_map),
+            Rc::clone(&ignore_path_set),
+            Rc::clone(&can_reset_errors),
+            config.hide_parse_errors(),
+        );
+        let parse_sess = RawParseSess::with_span_handler(handler, source_map);
+
+        Ok(ParseSess {
+            parse_sess,
+            ignore_path_set,
+            can_reset_errors,
+        })
+    }
+
+    pub(crate) fn default_submod_path(
+        &self,
+        id: ast::Ident,
+        relative: Option<ast::Ident>,
+        dir_path: &Path,
+    ) -> rustc_expand::module::ModulePath<'_> {
+        rustc_expand::module::default_submod_path(
+            &self.parse_sess,
+            id,
+            rustc_span::DUMMY_SP,
+            relative,
+            dir_path,
+        )
+    }
+
+    pub(crate) fn is_file_parsed(&self, path: &Path) -> bool {
+        self.parse_sess
+            .source_map()
+            .get_source_file(&rustc_span::FileName::Real(path.to_path_buf()))
+            .is_some()
+    }
+
+    pub(crate) fn ignore_file(&self, path: &FileName) -> bool {
+        self.ignore_path_set.as_ref().is_match(&path)
+    }
+
+    pub(crate) fn set_silent_emitter(&mut self) {
+        self.parse_sess.span_diagnostic = Handler::with_emitter(true, None, silent_emitter());
+    }
+
+    pub(crate) fn span_to_filename(&self, span: Span) -> FileName {
+        self.parse_sess.source_map().span_to_filename(span).into()
+    }
+
+    pub(crate) fn span_to_first_line_string(&self, span: Span) -> String {
+        let file_lines = self.parse_sess.source_map().span_to_lines(span).ok();
+
+        match file_lines {
+            Some(fl) => fl
+                .file
+                .get_line(fl.lines[0].line_index)
+                .map_or_else(String::new, |s| s.to_string()),
+            None => String::new(),
+        }
+    }
+
+    pub(crate) fn line_of_byte_pos(&self, pos: BytePos) -> usize {
+        self.parse_sess.source_map().lookup_char_pos(pos).line
+    }
+
+    pub(crate) fn span_to_debug_info(&self, span: Span) -> String {
+        self.parse_sess.source_map().span_to_string(span)
+    }
+
+    pub(crate) fn inner(&self) -> &RawParseSess {
+        &self.parse_sess
+    }
+
+    pub(crate) fn snippet_provider(&self, span: Span) -> SnippetProvider {
+        let source_file = self.parse_sess.source_map().lookup_char_pos(span.lo()).file;
+        SnippetProvider::new(
+            source_file.start_pos,
+            source_file.end_pos,
+            Rc::clone(source_file.src.as_ref().unwrap()),
+        )
+    }
+
+    pub(crate) fn get_original_snippet(&self, file_name: &FileName) -> Option<Rc<String>> {
+        self.parse_sess
+            .source_map()
+            .get_source_file(&file_name.into())
+            .and_then(|source_file| source_file.src.clone())
+    }
+}
+
+// Methods that should be restricted within the syntux module.
+impl ParseSess {
+    pub(super) fn emit_diagnostics(&self, diagnostics: Vec<Diagnostic>) {
+        for diagnostic in diagnostics {
+            self.parse_sess.span_diagnostic.emit_diagnostic(&diagnostic);
+        }
+    }
+
+    pub(super) fn can_reset_errors(&self) -> bool {
+        *self.can_reset_errors.borrow()
+    }
+
+    pub(super) fn has_errors(&self) -> bool {
+        self.parse_sess.span_diagnostic.has_errors()
+    }
+
+    pub(super) fn reset_errors(&self) {
+        self.parse_sess.span_diagnostic.reset_err_count();
+    }
+}
+
+impl LineRangeUtils for ParseSess {
+    fn lookup_line_range(&self, span: Span) -> LineRange {
+        let snippet = self
+            .parse_sess
+            .source_map()
+            .span_to_snippet(span)
+            .unwrap_or_default();
+        let lo = self.parse_sess.source_map().lookup_line(span.lo()).unwrap();
+        let hi = self.parse_sess.source_map().lookup_line(span.hi()).unwrap();
+
+        debug_assert_eq!(
+            lo.sf.name, hi.sf.name,
+            "span crossed file boundary: lo: {:?}, hi: {:?}",
+            lo, hi
+        );
+
+        // in case the span starts with a newline, the line range is off by 1 without the
+        // adjustment below
+        let offset = 1 + if starts_with_newline(&snippet) { 1 } else { 0 };
+        // Line numbers start at 1
+        LineRange {
+            file: lo.sf.clone(),
+            lo: lo.line + offset,
+            hi: hi.line + offset,
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    mod emitter {
+        use super::*;
+        use crate::config::IgnoreList;
+        use crate::is_nightly_channel;
+        use crate::utils::mk_sp;
+        use rustc_span::{FileName as SourceMapFileName, MultiSpan, DUMMY_SP};
+        use std::path::PathBuf;
+
+        struct TestEmitter {
+            num_emitted_errors: Rc<RefCell<u32>>,
+        }
+
+        impl Emitter for TestEmitter {
+            fn source_map(&self) -> Option<&Lrc<SourceMap>> {
+                None
+            }
+            fn emit_diagnostic(&mut self, _db: &Diagnostic) {
+                *self.num_emitted_errors.borrow_mut() += 1;
+            }
+        }
+
+        fn build_diagnostic(level: DiagnosticLevel, span: Option<MultiSpan>) -> Diagnostic {
+            Diagnostic {
+                level,
+                code: None,
+                message: vec![],
+                children: vec![],
+                suggestions: vec![],
+                span: span.unwrap_or_else(MultiSpan::new),
+                sort_span: DUMMY_SP,
+            }
+        }
+
+        fn build_emitter(
+            num_emitted_errors: Rc<RefCell<u32>>,
+            can_reset: Rc<RefCell<bool>>,
+            source_map: Option<Rc<SourceMap>>,
+            ignore_list: Option<IgnoreList>,
+        ) -> SilentOnIgnoredFilesEmitter {
+            let emitter_writer = TestEmitter { num_emitted_errors };
+            let source_map =
+                source_map.unwrap_or_else(|| Rc::new(SourceMap::new(FilePathMapping::empty())));
+            let ignore_path_set =
+                Rc::new(IgnorePathSet::from_ignore_list(&ignore_list.unwrap_or_default()).unwrap());
+            SilentOnIgnoredFilesEmitter {
+                has_non_ignorable_parser_errors: false,
+                source_map,
+                emitter: Box::new(emitter_writer),
+                ignore_path_set,
+                can_reset,
+            }
+        }
+
+        fn get_ignore_list(config: &str) -> IgnoreList {
+            Config::from_toml(config, Path::new("")).unwrap().ignore()
+        }
+
+        #[test]
+        fn handles_fatal_parse_error_in_ignored_file() {
+            let num_emitted_errors = Rc::new(RefCell::new(0));
+            let can_reset_errors = Rc::new(RefCell::new(false));
+            let ignore_list = get_ignore_list(r#"ignore = ["foo.rs"]"#);
+            let source_map = Rc::new(SourceMap::new(FilePathMapping::empty()));
+            let source =
+                String::from(r#"extern "system" fn jni_symbol!( funcName ) ( ... ) -> {} "#);
+            source_map.new_source_file(SourceMapFileName::Real(PathBuf::from("foo.rs")), source);
+            let mut emitter = build_emitter(
+                Rc::clone(&num_emitted_errors),
+                Rc::clone(&can_reset_errors),
+                Some(Rc::clone(&source_map)),
+                Some(ignore_list),
+            );
+            let span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1)));
+            let fatal_diagnostic = build_diagnostic(DiagnosticLevel::Fatal, Some(span));
+            emitter.emit_diagnostic(&fatal_diagnostic);
+            assert_eq!(*num_emitted_errors.borrow(), 1);
+            assert_eq!(*can_reset_errors.borrow(), false);
+        }
+
+        #[test]
+        fn handles_recoverable_parse_error_in_ignored_file() {
+            if !is_nightly_channel!() {
+                return;
+            }
+            let num_emitted_errors = Rc::new(RefCell::new(0));
+            let can_reset_errors = Rc::new(RefCell::new(false));
+            let ignore_list = get_ignore_list(r#"ignore = ["foo.rs"]"#);
+            let source_map = Rc::new(SourceMap::new(FilePathMapping::empty()));
+            let source = String::from(r#"pub fn bar() { 1x; }"#);
+            source_map.new_source_file(SourceMapFileName::Real(PathBuf::from("foo.rs")), source);
+            let mut emitter = build_emitter(
+                Rc::clone(&num_emitted_errors),
+                Rc::clone(&can_reset_errors),
+                Some(Rc::clone(&source_map)),
+                Some(ignore_list),
+            );
+            let span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1)));
+            let non_fatal_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(span));
+            emitter.emit_diagnostic(&non_fatal_diagnostic);
+            assert_eq!(*num_emitted_errors.borrow(), 0);
+            assert_eq!(*can_reset_errors.borrow(), true);
+        }
+
+        #[test]
+        fn handles_recoverable_parse_error_in_non_ignored_file() {
+            if !is_nightly_channel!() {
+                return;
+            }
+            let num_emitted_errors = Rc::new(RefCell::new(0));
+            let can_reset_errors = Rc::new(RefCell::new(false));
+            let source_map = Rc::new(SourceMap::new(FilePathMapping::empty()));
+            let source = String::from(r#"pub fn bar() { 1x; }"#);
+            source_map.new_source_file(SourceMapFileName::Real(PathBuf::from("foo.rs")), source);
+            let mut emitter = build_emitter(
+                Rc::clone(&num_emitted_errors),
+                Rc::clone(&can_reset_errors),
+                Some(Rc::clone(&source_map)),
+                None,
+            );
+            let span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1)));
+            let non_fatal_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(span));
+            emitter.emit_diagnostic(&non_fatal_diagnostic);
+            assert_eq!(*num_emitted_errors.borrow(), 1);
+            assert_eq!(*can_reset_errors.borrow(), false);
+        }
+
+        #[test]
+        fn handles_mix_of_recoverable_parse_error() {
+            if !is_nightly_channel!() {
+                return;
+            }
+            let num_emitted_errors = Rc::new(RefCell::new(0));
+            let can_reset_errors = Rc::new(RefCell::new(false));
+            let source_map = Rc::new(SourceMap::new(FilePathMapping::empty()));
+            let ignore_list = get_ignore_list(r#"ignore = ["foo.rs"]"#);
+            let bar_source = String::from(r#"pub fn bar() { 1x; }"#);
+            let foo_source = String::from(r#"pub fn foo() { 1x; }"#);
+            let fatal_source =
+                String::from(r#"extern "system" fn jni_symbol!( funcName ) ( ... ) -> {} "#);
+            source_map
+                .new_source_file(SourceMapFileName::Real(PathBuf::from("bar.rs")), bar_source);
+            source_map
+                .new_source_file(SourceMapFileName::Real(PathBuf::from("foo.rs")), foo_source);
+            source_map.new_source_file(
+                SourceMapFileName::Real(PathBuf::from("fatal.rs")),
+                fatal_source,
+            );
+            let mut emitter = build_emitter(
+                Rc::clone(&num_emitted_errors),
+                Rc::clone(&can_reset_errors),
+                Some(Rc::clone(&source_map)),
+                Some(ignore_list),
+            );
+            let bar_span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1)));
+            let foo_span = MultiSpan::from_span(mk_sp(BytePos(21), BytePos(22)));
+            let bar_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(bar_span));
+            let foo_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(foo_span));
+            let fatal_diagnostic = build_diagnostic(DiagnosticLevel::Fatal, None);
+            emitter.emit_diagnostic(&bar_diagnostic);
+            emitter.emit_diagnostic(&foo_diagnostic);
+            emitter.emit_diagnostic(&fatal_diagnostic);
+            assert_eq!(*num_emitted_errors.borrow(), 2);
+            assert_eq!(*can_reset_errors.borrow(), false);
+        }
+    }
+}
diff --git a/src/types.rs b/src/types.rs
index efc85efc5c4..4f92ff6246f 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -1,8 +1,8 @@
 use std::iter::ExactSizeIterator;
 use std::ops::Deref;
 
+use rustc_ast::ast::{self, FnRetTy, Mutability};
 use rustc_span::{symbol::kw, BytePos, Span};
-use syntax::ast::{self, FunctionRetTy, Mutability};
 
 use crate::config::lists::*;
 use crate::config::{IndentStyle, TypeDensity, Version};
@@ -233,14 +233,18 @@ fn rewrite_segment(
 
     if let Some(ref args) = segment.args {
         match **args {
-            ast::GenericArgs::AngleBracketed(ref data)
-                if !data.args.is_empty() || !data.constraints.is_empty() =>
-            {
+            ast::GenericArgs::AngleBracketed(ref data) if !data.args.is_empty() => {
                 let param_list = data
                     .args
                     .iter()
-                    .map(SegmentParam::from_generic_arg)
-                    .chain(data.constraints.iter().map(|x| SegmentParam::Binding(&*x)))
+                    .map(|x| match x {
+                        ast::AngleBracketedArg::Arg(generic_arg) => {
+                            SegmentParam::from_generic_arg(generic_arg)
+                        }
+                        ast::AngleBracketedArg::Constraint(constraint) => {
+                            SegmentParam::Binding(constraint)
+                        }
+                    })
                     .collect::<Vec<_>>();
 
                 // HACK: squeeze out the span between the identifier and the parameters.
@@ -292,7 +296,7 @@ fn rewrite_segment(
 
 fn format_function_type<'a, I>(
     inputs: I,
-    output: &FunctionRetTy,
+    output: &FnRetTy,
     variadic: bool,
     span: Span,
     context: &RewriteContext<'_>,
@@ -311,11 +315,11 @@ where
         IndentStyle::Visual => shape.block_left(4)?,
     };
     let output = match *output {
-        FunctionRetTy::Ty(ref ty) => {
+        FnRetTy::Ty(ref ty) => {
             let type_str = ty.rewrite(context, ty_shape)?;
             format!(" -> {}", type_str)
         }
-        FunctionRetTy::Default(..) => String::new(),
+        FnRetTy::Default(..) => String::new(),
     };
 
     let list_shape = if context.use_block_indent() {
@@ -551,7 +555,7 @@ impl Rewrite for ast::GenericParam {
             _ => (),
         }
 
-        if let syntax::ast::GenericParamKind::Const { ref ty } = &self.kind {
+        if let rustc_ast::ast::GenericParamKind::Const { ref ty } = &self.kind {
             result.push_str("const ");
             result.push_str(rewrite_ident(context, self.ident));
             result.push_str(": ");
@@ -732,7 +736,7 @@ impl Rewrite for ast::Ty {
             }
             ast::TyKind::BareFn(ref bare_fn) => rewrite_bare_fn(bare_fn, self.span, context, shape),
             ast::TyKind::Never => Some(String::from("!")),
-            ast::TyKind::Mac(ref mac) => {
+            ast::TyKind::MacCall(ref mac) => {
                 rewrite_macro(mac, None, context, shape, MacroPosition::Expression)
             }
             ast::TyKind::ImplicitSelf => Some(String::from("")),
diff --git a/src/utils.rs b/src/utils.rs
index e0971c7d1bf..41400399ddd 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -1,13 +1,13 @@
 use std::borrow::Cow;
 
-use rustc_ast_pretty::pprust;
-use rustc_span::{sym, BytePos, ExpnId, Span, Symbol, SyntaxContext};
-use rustc_target::spec::abi;
-use syntax::ast::{
+use rustc_ast::ast::{
     self, Attribute, CrateSugar, MetaItem, MetaItemKind, NestedMetaItem, NodeId, Path, Visibility,
     VisibilityKind,
 };
-use syntax::ptr;
+use rustc_ast::ptr;
+use rustc_ast_pretty::pprust;
+use rustc_span::{sym, BytePos, ExpnId, Span, Symbol, SyntaxContext};
+use rustc_target::spec::abi;
 use unicode_width::UnicodeWidthStr;
 
 use crate::comment::{filter_normal_code, CharClasses, FullCodeCharKind, LineClasses};
@@ -86,34 +86,34 @@ pub(crate) fn format_visibility(
 }
 
 #[inline]
-pub(crate) fn format_async(is_async: &ast::IsAsync) -> &'static str {
+pub(crate) fn format_async(is_async: &ast::Async) -> &'static str {
     match is_async {
-        ast::IsAsync::Async { .. } => "async ",
-        ast::IsAsync::NotAsync => "",
+        ast::Async::Yes { .. } => "async ",
+        ast::Async::No => "",
     }
 }
 
 #[inline]
-pub(crate) fn format_constness(constness: ast::Constness) -> &'static str {
+pub(crate) fn format_constness(constness: ast::Const) -> &'static str {
     match constness {
-        ast::Constness::Const => "const ",
-        ast::Constness::NotConst => "",
+        ast::Const::Yes(..) => "const ",
+        ast::Const::No => "",
     }
 }
 
 #[inline]
 pub(crate) fn format_defaultness(defaultness: ast::Defaultness) -> &'static str {
     match defaultness {
-        ast::Defaultness::Default => "default ",
+        ast::Defaultness::Default(..) => "default ",
         ast::Defaultness::Final => "",
     }
 }
 
 #[inline]
-pub(crate) fn format_unsafety(unsafety: ast::Unsafety) -> &'static str {
+pub(crate) fn format_unsafety(unsafety: ast::Unsafe) -> &'static str {
     match unsafety {
-        ast::Unsafety::Unsafe => "unsafe ",
-        ast::Unsafety::Normal => "",
+        ast::Unsafe::Yes(..) => "unsafe ",
+        ast::Unsafe::No => "",
     }
 }
 
@@ -157,7 +157,7 @@ pub(crate) fn format_extern(
 }
 
 #[inline]
-// Transform `Vec<syntax::ptr::P<T>>` into `Vec<&T>`
+// Transform `Vec<rustc_ast::ptr::P<T>>` into `Vec<&T>`
 pub(crate) fn ptr_vec_to_ref_vec<T>(vec: &[ptr::P<T>]) -> Vec<&T> {
     vec.iter().map(|x| &**x).collect::<Vec<_>>()
 }
@@ -355,7 +355,7 @@ macro_rules! out_of_file_lines_range {
             && !$self
                 .config
                 .file_lines()
-                .intersects(&$self.source_map.lookup_line_range($span))
+                .intersects(&$self.parse_sess.lookup_line_range($span))
     };
 }
 
@@ -456,7 +456,7 @@ pub(crate) fn first_line_ends_with(s: &str, c: char) -> bool {
 // parens, braces, and brackets in its idiomatic formatting.
 pub(crate) fn is_block_expr(context: &RewriteContext<'_>, expr: &ast::Expr, repr: &str) -> bool {
     match expr.kind {
-        ast::ExprKind::Mac(..)
+        ast::ExprKind::MacCall(..)
         | ast::ExprKind::Call(..)
         | ast::ExprKind::MethodCall(..)
         | ast::ExprKind::Array(..)
@@ -490,7 +490,7 @@ pub(crate) fn is_block_expr(context: &RewriteContext<'_>, expr: &ast::Expr, repr
         | ast::ExprKind::Continue(..)
         | ast::ExprKind::Err
         | ast::ExprKind::Field(..)
-        | ast::ExprKind::InlineAsm(..)
+        | ast::ExprKind::LlvmInlineAsm(..)
         | ast::ExprKind::Let(..)
         | ast::ExprKind::Path(..)
         | ast::ExprKind::Range(..)
diff --git a/src/vertical.rs b/src/vertical.rs
index b932b0afa17..95d1d5c2d7e 100644
--- a/src/vertical.rs
+++ b/src/vertical.rs
@@ -3,8 +3,8 @@
 use std::cmp;
 
 use itertools::Itertools;
+use rustc_ast::ast;
 use rustc_span::{BytePos, Span};
-use syntax::ast;
 
 use crate::comment::combine_strs_with_missing_comments;
 use crate::config::lists::*;
diff --git a/src/visitor.rs b/src/visitor.rs
index c6ae3b3be1e..346628c0b89 100644
--- a/src/visitor.rs
+++ b/src/visitor.rs
@@ -1,13 +1,9 @@
 use std::cell::{Cell, RefCell};
 use std::rc::Rc;
 
-use rustc_session::parse::ParseSess;
-use rustc_span::{
-    source_map::{self, SourceMap},
-    BytePos, Pos, Span,
-};
-use syntax::token::DelimToken;
-use syntax::{ast, visit};
+use rustc_ast::token::DelimToken;
+use rustc_ast::{ast, visit};
+use rustc_span::{BytePos, Pos, Span};
 
 use crate::attr::*;
 use crate::comment::{rewrite_comment, CodeCharKind, CommentCodeSlices};
@@ -27,6 +23,7 @@ use crate::skip::{is_skip_attr, SkipContext};
 use crate::source_map::{LineRangeUtils, SpanUtils};
 use crate::spanned::Spanned;
 use crate::stmt::Stmt;
+use crate::syntux::session::ParseSess;
 use crate::utils::{
     self, contains_skip, count_newlines, depr_skip_annotation, inner_attributes, last_line_width,
     mk_sp, ptr_vec_to_ref_vec, rewrite_ident, stmt_expr,
@@ -34,23 +31,23 @@ use crate::utils::{
 use crate::{ErrorKind, FormatReport, FormattingError};
 
 /// Creates a string slice corresponding to the specified span.
-pub(crate) struct SnippetProvider<'a> {
+pub(crate) struct SnippetProvider {
     /// A pointer to the content of the file we are formatting.
-    big_snippet: &'a str,
+    big_snippet: Rc<String>,
     /// A position of the start of `big_snippet`, used as an offset.
     start_pos: usize,
     /// A end position of the file that this snippet lives.
     end_pos: usize,
 }
 
-impl<'a> SnippetProvider<'a> {
+impl SnippetProvider {
     pub(crate) fn span_to_snippet(&self, span: Span) -> Option<&str> {
         let start_index = span.lo().to_usize().checked_sub(self.start_pos)?;
         let end_index = span.hi().to_usize().checked_sub(self.start_pos)?;
         Some(&self.big_snippet[start_index..end_index])
     }
 
-    pub(crate) fn new(start_pos: BytePos, end_pos: BytePos, big_snippet: &'a str) -> Self {
+    pub(crate) fn new(start_pos: BytePos, end_pos: BytePos, big_snippet: Rc<String>) -> Self {
         let start_pos = start_pos.to_usize();
         let end_pos = end_pos.to_usize();
         SnippetProvider {
@@ -60,6 +57,14 @@ impl<'a> SnippetProvider<'a> {
         }
     }
 
+    pub(crate) fn entire_snippet(&self) -> &str {
+        self.big_snippet.as_str()
+    }
+
+    pub(crate) fn start_pos(&self) -> BytePos {
+        BytePos::from_usize(self.start_pos)
+    }
+
     pub(crate) fn end_pos(&self) -> BytePos {
         BytePos::from_usize(self.end_pos)
     }
@@ -67,15 +72,14 @@ impl<'a> SnippetProvider<'a> {
 
 pub(crate) struct FmtVisitor<'a> {
     parent_context: Option<&'a RewriteContext<'a>>,
-    pub(crate) parse_session: &'a ParseSess,
-    pub(crate) source_map: &'a SourceMap,
+    pub(crate) parse_sess: &'a ParseSess,
     pub(crate) buffer: String,
     pub(crate) last_pos: BytePos,
     // FIXME: use an RAII util or closure for indenting
     pub(crate) block_indent: Indent,
     pub(crate) config: &'a Config,
     pub(crate) is_if_else_block: bool,
-    pub(crate) snippet_provider: &'a SnippetProvider<'a>,
+    pub(crate) snippet_provider: &'a SnippetProvider,
     pub(crate) line_number: usize,
     /// List of 1-based line ranges which were annotated with skip
     /// Both bounds are inclusifs.
@@ -110,10 +114,8 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
 
     fn visit_stmt(&mut self, stmt: &Stmt<'_>) {
         debug!(
-            "visit_stmt: {:?} {:?} `{}`",
-            self.source_map.lookup_char_pos(stmt.span().lo()),
-            self.source_map.lookup_char_pos(stmt.span().hi()),
-            self.snippet(stmt.span()),
+            "visit_stmt: {}",
+            self.parse_sess.span_to_debug_info(stmt.span())
         );
 
         // https://github.com/rust-lang/rust/issues/63679.
@@ -144,7 +146,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
                     self.push_rewrite(stmt.span(), rewrite)
                 }
             }
-            ast::StmtKind::Mac(ref mac) => {
+            ast::StmtKind::MacCall(ref mac) => {
                 let (ref mac, _macro_style, ref attrs) = **mac;
                 if self.visit_attrs(attrs, ast::AttrStyle::Outer) {
                     self.push_skipped_with_span(
@@ -157,6 +159,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
                 }
                 self.format_missing(stmt.span().hi());
             }
+            ast::StmtKind::Empty => (),
         }
     }
 
@@ -195,9 +198,8 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
         has_braces: bool,
     ) {
         debug!(
-            "visit_block: {:?} {:?}",
-            self.source_map.lookup_char_pos(b.span.lo()),
-            self.source_map.lookup_char_pos(b.span.hi())
+            "visit_block: {}",
+            self.parse_sess.span_to_debug_info(b.span),
         );
 
         // Check if this block has braces.
@@ -497,7 +499,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
                     self.format_missing_with_indent(source!(self, item.span).lo());
                     self.format_mod(module, &item.vis, item.span, item.ident, attrs, is_inline);
                 }
-                ast::ItemKind::Mac(ref mac) => {
+                ast::ItemKind::MacCall(ref mac) => {
                     self.visit_mac(mac, Some(item.ident), MacroPosition::Item);
                 }
                 ast::ItemKind::ForeignMod(ref foreign_mod) => {
@@ -507,7 +509,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
                 ast::ItemKind::Static(..) | ast::ItemKind::Const(..) => {
                     self.visit_static(&StaticParts::from_item(item));
                 }
-                ast::ItemKind::Fn(ref fn_signature, ref generics, ref body) => {
+                ast::ItemKind::Fn(defaultness, ref fn_signature, ref generics, Some(ref body)) => {
                     let inner_attrs = inner_attributes(&item.attrs);
                     let fn_ctxt = match fn_signature.header.ext {
                         ast::Extern::None => visit::FnCtxt::Free,
@@ -519,28 +521,40 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
                             item.ident,
                             &fn_signature,
                             &item.vis,
-                            body.as_deref(),
+                            Some(body),
                         ),
                         generics,
                         &fn_signature.decl,
                         item.span,
-                        ast::Defaultness::Final,
+                        defaultness,
                         Some(&inner_attrs),
                     )
                 }
-                ast::ItemKind::TyAlias(ref ty, ref generics) => match ty.kind.opaque_top_hack() {
-                    None => {
+                ast::ItemKind::Fn(_, ref fn_signature, ref generics, None) => {
+                    let indent = self.block_indent;
+                    let rewrite = self.rewrite_required_fn(
+                        indent,
+                        item.ident,
+                        &fn_signature,
+                        generics,
+                        item.span,
+                    );
+
+                    self.push_rewrite(item.span, rewrite);
+                }
+                ast::ItemKind::TyAlias(_, ref generics, ref generic_bounds, ref ty) => match ty {
+                    Some(ty) => {
                         let rewrite = rewrite_type_alias(
                             &self.get_context(),
                             self.block_indent,
                             item.ident,
-                            ty,
+                            &*ty,
                             generics,
                             &item.vis,
                         );
                         self.push_rewrite(item.span, rewrite);
                     }
-                    Some(generic_bounds) => {
+                    None => {
                         let rewrite = rewrite_opaque_type(
                             &self.get_context(),
                             self.block_indent,
@@ -583,37 +597,36 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
 
         match ti.kind {
             ast::AssocItemKind::Const(..) => self.visit_static(&StaticParts::from_trait_item(ti)),
-            ast::AssocItemKind::Fn(ref sig, None) => {
+            ast::AssocItemKind::Fn(_, ref sig, ref generics, None) => {
                 let indent = self.block_indent;
-                let rewrite =
-                    self.rewrite_required_fn(indent, ti.ident, sig, &ti.generics, ti.span);
+                let rewrite = self.rewrite_required_fn(indent, ti.ident, sig, generics, ti.span);
                 self.push_rewrite(ti.span, rewrite);
             }
-            ast::AssocItemKind::Fn(ref sig, Some(ref body)) => {
+            ast::AssocItemKind::Fn(defaultness, ref sig, ref generics, Some(ref body)) => {
                 let inner_attrs = inner_attributes(&ti.attrs);
                 let vis = rustc_span::source_map::dummy_spanned(ast::VisibilityKind::Inherited);
                 let fn_ctxt = visit::FnCtxt::Assoc(visit::AssocCtxt::Trait);
                 self.visit_fn(
                     visit::FnKind::Fn(fn_ctxt, ti.ident, sig, &vis, Some(body)),
-                    &ti.generics,
+                    generics,
                     &sig.decl,
                     ti.span,
-                    ast::Defaultness::Final,
+                    defaultness,
                     Some(&inner_attrs),
                 );
             }
-            ast::AssocItemKind::TyAlias(ref generic_bounds, ref type_default) => {
+            ast::AssocItemKind::TyAlias(_, ref generics, ref generic_bounds, ref type_default) => {
                 let rewrite = rewrite_associated_type(
                     ti.ident,
                     type_default.as_ref(),
-                    &ti.generics,
+                    generics,
                     Some(generic_bounds),
                     &self.get_context(),
                     self.block_indent,
                 );
                 self.push_rewrite(ti.span, rewrite);
             }
-            ast::AssocItemKind::Macro(ref mac) => {
+            ast::AssocItemKind::MacCall(ref mac) => {
                 self.visit_mac(mac, Some(ti.ident), MacroPosition::Item);
             }
         }
@@ -628,32 +641,31 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
         }
 
         match ii.kind {
-            ast::AssocItemKind::Fn(ref sig, Some(ref body)) => {
+            ast::AssocItemKind::Fn(defaultness, ref sig, ref generics, Some(ref body)) => {
                 let inner_attrs = inner_attributes(&ii.attrs);
                 let fn_ctxt = visit::FnCtxt::Assoc(visit::AssocCtxt::Impl);
                 self.visit_fn(
                     visit::FnKind::Fn(fn_ctxt, ii.ident, sig, &ii.vis, Some(body)),
-                    &ii.generics,
+                    generics,
                     &sig.decl,
                     ii.span,
-                    ii.defaultness,
+                    defaultness,
                     Some(&inner_attrs),
                 );
             }
-            ast::AssocItemKind::Fn(ref sig, None) => {
+            ast::AssocItemKind::Fn(_, ref sig, ref generics, None) => {
                 let indent = self.block_indent;
-                let rewrite =
-                    self.rewrite_required_fn(indent, ii.ident, sig, &ii.generics, ii.span);
+                let rewrite = self.rewrite_required_fn(indent, ii.ident, sig, generics, ii.span);
                 self.push_rewrite(ii.span, rewrite);
             }
             ast::AssocItemKind::Const(..) => self.visit_static(&StaticParts::from_impl_item(ii)),
-            ast::AssocItemKind::TyAlias(_, ref ty) => {
+            ast::AssocItemKind::TyAlias(defaultness, ref generics, _, ref ty) => {
                 let rewrite_associated = || {
                     rewrite_associated_impl_type(
                         ii.ident,
-                        ii.defaultness,
+                        defaultness,
                         ty.as_ref(),
-                        &ii.generics,
+                        &generics,
                         &self.get_context(),
                         self.block_indent,
                     )
@@ -664,7 +676,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
                         Some(generic_bounds) => rewrite_opaque_impl_type(
                             &self.get_context(),
                             ii.ident,
-                            &ii.generics,
+                            generics,
                             generic_bounds,
                             self.block_indent,
                         ),
@@ -673,13 +685,13 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
                 };
                 self.push_rewrite(ii.span, rewrite);
             }
-            ast::AssocItemKind::Macro(ref mac) => {
+            ast::AssocItemKind::MacCall(ref mac) => {
                 self.visit_mac(mac, Some(ii.ident), MacroPosition::Item);
             }
         }
     }
 
-    fn visit_mac(&mut self, mac: &ast::Mac, ident: Option<ast::Ident>, pos: MacroPosition) {
+    fn visit_mac(&mut self, mac: &ast::MacCall, ident: Option<ast::Ident>, pos: MacroPosition) {
         skip_out_of_file_lines_range_visitor!(self, mac.span());
 
         // 1 = ;
@@ -740,10 +752,10 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
         // do not take into account the lines with attributes as part of the skipped range
         let attrs_end = attrs
             .iter()
-            .map(|attr| self.source_map.lookup_char_pos(attr.span.hi()).line)
+            .map(|attr| self.parse_sess.line_of_byte_pos(attr.span.hi()))
             .max()
             .unwrap_or(1);
-        let first_line = self.source_map.lookup_char_pos(main_span.lo()).line;
+        let first_line = self.parse_sess.line_of_byte_pos(main_span.lo());
         // Statement can start after some newlines and/or spaces
         // or it can be on the same line as the last attribute.
         // So here we need to take a minimum between the two.
@@ -754,8 +766,8 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
     }
 
     pub(crate) fn from_context(ctx: &'a RewriteContext<'_>) -> FmtVisitor<'a> {
-        let mut visitor = FmtVisitor::from_source_map(
-            ctx.parse_session,
+        let mut visitor = FmtVisitor::from_parse_sess(
+            ctx.parse_sess,
             ctx.config,
             ctx.snippet_provider,
             ctx.report.clone(),
@@ -765,16 +777,15 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
         visitor
     }
 
-    pub(crate) fn from_source_map(
+    pub(crate) fn from_parse_sess(
         parse_session: &'a ParseSess,
         config: &'a Config,
-        snippet_provider: &'a SnippetProvider<'_>,
+        snippet_provider: &'a SnippetProvider,
         report: FormatReport,
     ) -> FmtVisitor<'a> {
         FmtVisitor {
             parent_context: None,
-            parse_session,
-            source_map: parse_session.source_map(),
+            parse_sess: parse_session,
             buffer: String::with_capacity(snippet_provider.big_snippet.len() * 2),
             last_pos: BytePos(0),
             block_indent: Indent::empty(),
@@ -801,12 +812,12 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
     pub(crate) fn visit_attrs(&mut self, attrs: &[ast::Attribute], style: ast::AttrStyle) -> bool {
         for attr in attrs {
             if attr.check_name(depr_skip_annotation()) {
-                let file_name = self.source_map.span_to_filename(attr.span).into();
+                let file_name = self.parse_sess.span_to_filename(attr.span);
                 self.report.append(
                     file_name,
                     vec![FormattingError::from_span(
                         attr.span,
-                        &self.source_map,
+                        self.parse_sess,
                         ErrorKind::DeprecatedAttr,
                     )],
                 );
@@ -815,12 +826,12 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
                     ast::AttrKind::Normal(ref attribute_item)
                         if self.is_unknown_rustfmt_attr(&attribute_item.path.segments) =>
                     {
-                        let file_name = self.source_map.span_to_filename(attr.span).into();
+                        let file_name = self.parse_sess.span_to_filename(attr.span);
                         self.report.append(
                             file_name,
                             vec![FormattingError::from_span(
                                 attr.span,
-                                self.source_map,
+                                self.parse_sess,
                                 ErrorKind::BadAttr,
                             )],
                         );
@@ -928,14 +939,10 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
         }
     }
 
-    pub(crate) fn format_separate_mod(
-        &mut self,
-        m: &ast::Mod,
-        source_file: &source_map::SourceFile,
-    ) {
+    pub(crate) fn format_separate_mod(&mut self, m: &ast::Mod, end_pos: BytePos) {
         self.block_indent = Indent::empty();
         self.walk_mod_items(m);
-        self.format_missing_with_indent(source_file.end_pos);
+        self.format_missing_with_indent(end_pos);
     }
 
     pub(crate) fn skip_empty_lines(&mut self, end_pos: BytePos) {
@@ -966,8 +973,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
 
     pub(crate) fn get_context(&self) -> RewriteContext<'_> {
         RewriteContext {
-            parse_session: self.parse_session,
-            source_map: self.source_map,
+            parse_sess: self.parse_sess,
             config: self.config,
             inside_macro: Rc::new(Cell::new(false)),
             use_block: Cell::new(false),
diff --git a/tests/source/imports.rs b/tests/source/imports.rs
index d0bdeda595d..4dfc6ed94e3 100644
--- a/tests/source/imports.rs
+++ b/tests/source/imports.rs
@@ -3,7 +3,7 @@
 // Imports.
 
 // Long import.
-use syntax::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic, ItemDefaultImpl};
+use rustc_ast::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic, ItemDefaultImpl};
 use exceedingly::looooooooooooooooooooooooooooooooooooooooooooooooooooooooooong::import::path::{ItemA, ItemB};
 use exceedingly::loooooooooooooooooooooooooooooooooooooooooooooooooooooooong::import::path::{ItemA, ItemB};
 
@@ -15,30 +15,30 @@ use list::{
 
 use test::{  Other          /* C   */  , /*   A   */ self  /*    B     */    };
 
-use syntax::{self};
+use rustc_ast::{self};
 use {/* Pre-comment! */
      Foo, Bar /* comment */};
 use Foo::{Bar, Baz};
-pub use syntax::ast::{Expr_, Expr, ExprAssign, ExprCall, ExprMethodCall, ExprPath};
+pub use rustc_ast::ast::{Expr_, Expr, ExprAssign, ExprCall, ExprMethodCall, ExprPath};
 
-use syntax::some::{};
+use rustc_ast::some::{};
 
 use self;
 use std::io::{self};
 use std::io::self;
 
 mod Foo {
-    pub use syntax::ast::{
+    pub use rustc_ast::ast::{
         ItemForeignMod,
-        ItemImpl, 
+        ItemImpl,
         ItemMac,
         ItemMod,
-        ItemStatic, 
+        ItemStatic,
         ItemDefaultImpl
     };
 
     mod Foo2 {
-        pub use syntax::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic, self, ItemDefaultImpl};
+        pub use rustc_ast::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic, self, ItemDefaultImpl};
     }
 }
 
diff --git a/tests/source/issue_4057.rs b/tests/source/issue_4057.rs
new file mode 100644
index 00000000000..7cd80734bd9
--- /dev/null
+++ b/tests/source/issue_4057.rs
@@ -0,0 +1,15 @@
+// rustfmt-format_code_in_doc_comments: true
+
+/// ```
+/// # #[rustversion::since(1.36)]
+/// # fn dox() {
+/// # use std::pin::Pin;
+/// # type Projection<'a> = &'a ();
+/// # type ProjectionRef<'a> = &'a ();
+/// # trait Dox {
+/// fn   project_ex (self: Pin<&mut Self>) -> Projection<'_>;
+/// fn   project_ref(self: Pin<&Self>) -> ProjectionRef<'_>;
+/// # }
+/// # }
+/// ```
+struct Foo;
diff --git a/tests/target/imports.rs b/tests/target/imports.rs
index c497a375b59..87584d89f66 100644
--- a/tests/target/imports.rs
+++ b/tests/target/imports.rs
@@ -9,7 +9,7 @@ use exceedingly::loooooooooooooooooooooooooooooooooooooooooooooooooooooooong::im
 use exceedingly::looooooooooooooooooooooooooooooooooooooooooooooooooooooooooong::import::path::{
     ItemA, ItemB,
 };
-use syntax::ast::{ItemDefaultImpl, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic};
+use rustc_ast::ast::{ItemDefaultImpl, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic};
 
 use list::{
     // Another item
@@ -22,8 +22,8 @@ use list::{
 
 use test::{/* A */ self /* B */, Other /* C */};
 
-pub use syntax::ast::{Expr, ExprAssign, ExprCall, ExprMethodCall, ExprPath, Expr_};
-use syntax::{self};
+pub use rustc_ast::ast::{Expr, ExprAssign, ExprCall, ExprMethodCall, ExprPath, Expr_};
+use rustc_ast::{self};
 use Foo::{Bar, Baz};
 use {Bar /* comment */, /* Pre-comment! */ Foo};
 
@@ -31,12 +31,12 @@ use std::io;
 use std::io::{self};
 
 mod Foo {
-    pub use syntax::ast::{
+    pub use rustc_ast::ast::{
         ItemDefaultImpl, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic,
     };
 
     mod Foo2 {
-        pub use syntax::ast::{
+        pub use rustc_ast::ast::{
             self, ItemDefaultImpl, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic,
         };
     }
diff --git a/tests/target/issue-4068.rs b/tests/target/issue-4068.rs
new file mode 100644
index 00000000000..cd8a1f2765f
--- /dev/null
+++ b/tests/target/issue-4068.rs
@@ -0,0 +1,3 @@
+fn main() {
+    extern "C" fn packet_records_options_impl_layout_length_encoding_option_len_multiplier();
+}
diff --git a/tests/target/issue_4057.rs b/tests/target/issue_4057.rs
new file mode 100644
index 00000000000..467e67bca7c
--- /dev/null
+++ b/tests/target/issue_4057.rs
@@ -0,0 +1,15 @@
+// rustfmt-format_code_in_doc_comments: true
+
+/// ```
+/// # #[rustversion::since(1.36)]
+/// # fn dox() {
+/// # use std::pin::Pin;
+/// # type Projection<'a> = &'a ();
+/// # type ProjectionRef<'a> = &'a ();
+/// # trait Dox {
+/// fn project_ex(self: Pin<&mut Self>) -> Projection<'_>;
+/// fn project_ref(self: Pin<&Self>) -> ProjectionRef<'_>;
+/// # }
+/// # }
+/// ```
+struct Foo;