From 0b713ae919705bfbc2ec5bf5eea74570f7ecc19a Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Tue, 13 Aug 2019 23:54:20 +0200
Subject: [PATCH 01/35] typeck: extract ban_private_field_access

---
 src/librustc_typeck/check/expr.rs | 50 ++++++++++++++++++++-----------
 1 file changed, 33 insertions(+), 17 deletions(-)

diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index 9680f61d69903..b4154c15d6739 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -24,6 +24,7 @@ use syntax::source_map::Span;
 use syntax::util::lev_distance::find_best_match_for_name;
 use rustc::hir;
 use rustc::hir::{ExprKind, QPath};
+use rustc::hir::def_id::DefId;
 use rustc::hir::def::{CtorKind, Res, DefKind};
 use rustc::hir::ptr::P;
 use rustc::infer;
@@ -1336,23 +1337,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         autoderef.unambiguous_final_ty(self);
 
         if let Some((did, field_ty)) = private_candidate {
-            let struct_path = self.tcx().def_path_str(did);
-            let mut err = struct_span_err!(self.tcx().sess, expr.span, E0616,
-                                           "field `{}` of struct `{}` is private",
-                                           field, struct_path);
-            // Also check if an accessible method exists, which is often what is meant.
-            if self.method_exists(field, expr_t, expr.hir_id, false)
-                && !self.expr_in_place(expr.hir_id)
-            {
-                self.suggest_method_call(
-                    &mut err,
-                    &format!("a method `{}` also exists, call it with parentheses", field),
-                    field,
-                    expr_t,
-                    expr.hir_id,
-                );
-            }
-            err.emit();
+            self.ban_private_field_access(expr, expr_t, field, did);
             field_ty
         } else if field.name == kw::Invalid {
             self.tcx().types.err
@@ -1446,6 +1431,37 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
+    fn ban_private_field_access(
+        &self,
+        expr: &'tcx hir::Expr,
+        expr_t: Ty<'tcx>,
+        field: ast::Ident,
+        def_id: DefId,
+    ) {
+        let struct_path = self.tcx().def_path_str(def_id);
+        let mut err = struct_span_err!(
+            self.tcx().sess,
+            expr.span,
+            E0616,
+            "field `{}` of struct `{}` is private",
+            field,
+            struct_path
+        );
+        // Also check if an accessible method exists, which is often what is meant.
+        if self.method_exists(field, expr_t, expr.hir_id, false)
+            && !self.expr_in_place(expr.hir_id)
+        {
+            self.suggest_method_call(
+                &mut err,
+                &format!("a method `{}` also exists, call it with parentheses", field),
+                field,
+                expr_t,
+                expr.hir_id,
+            );
+        }
+        err.emit();
+    }
+
     fn no_such_field_err<T: Display>(&self, span: Span, field: T, expr_t: &ty::TyS<'_>)
         -> DiagnosticBuilder<'_> {
         type_error_struct!(self.tcx().sess, span, expr_t, E0609,

From 5e019def0d8c277ef7b82d9348350ed1fc8747db Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Tue, 13 Aug 2019 23:59:22 +0200
Subject: [PATCH 02/35] typeck: extract ban_take_value_of_method

---
 src/librustc_typeck/check/expr.rs | 48 +++++++++++++++++++------------
 1 file changed, 29 insertions(+), 19 deletions(-)

diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index b4154c15d6739..c25a60d065d6b 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -1342,23 +1342,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         } else if field.name == kw::Invalid {
             self.tcx().types.err
         } else if self.method_exists(field, expr_t, expr.hir_id, true) {
-            let mut err = type_error_struct!(self.tcx().sess, field.span, expr_t, E0615,
-                               "attempted to take value of method `{}` on type `{}`",
-                               field, expr_t);
-
-            if !self.expr_in_place(expr.hir_id) {
-                self.suggest_method_call(
-                    &mut err,
-                    "use parentheses to call the method",
-                    field,
-                    expr_t,
-                    expr.hir_id
-                );
-            } else {
-                err.help("methods are immutable and cannot be assigned to");
-            }
-
-            err.emit();
+            self.ban_take_value_of_method(expr, expr_t, field);
             self.tcx().types.err
         } else {
             if !expr_t.is_primitive_ty() {
@@ -1436,9 +1420,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expr: &'tcx hir::Expr,
         expr_t: Ty<'tcx>,
         field: ast::Ident,
-        def_id: DefId,
+        base_did: DefId,
     ) {
-        let struct_path = self.tcx().def_path_str(def_id);
+        let struct_path = self.tcx().def_path_str(base_did);
         let mut err = struct_span_err!(
             self.tcx().sess,
             expr.span,
@@ -1462,6 +1446,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         err.emit();
     }
 
+    fn ban_take_value_of_method(&self, expr: &'tcx hir::Expr, expr_t: Ty<'tcx>, field: ast::Ident) {
+        let mut err = type_error_struct!(
+            self.tcx().sess,
+            field.span,
+            expr_t,
+            E0615,
+            "attempted to take value of method `{}` on type `{}`",
+            field,
+            expr_t
+        );
+
+        if !self.expr_in_place(expr.hir_id) {
+            self.suggest_method_call(
+                &mut err,
+                "use parentheses to call the method",
+                field,
+                expr_t,
+                expr.hir_id
+            );
+        } else {
+            err.help("methods are immutable and cannot be assigned to");
+        }
+
+        err.emit();
+    }
+
     fn no_such_field_err<T: Display>(&self, span: Span, field: T, expr_t: &ty::TyS<'_>)
         -> DiagnosticBuilder<'_> {
         type_error_struct!(self.tcx().sess, span, expr_t, E0609,

From 98058468815a62be36875ed0e990bbcbcd4a42b4 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Wed, 14 Aug 2019 00:30:06 +0200
Subject: [PATCH 03/35] typeck: extract maybe_suggest_array_indexing

---
 src/librustc_typeck/check/expr.rs | 50 ++++++++++++++++++-------------
 1 file changed, 29 insertions(+), 21 deletions(-)

diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index c25a60d065d6b..20a47441375ba 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -1370,25 +1370,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             };
                     }
                     ty::Array(_, len) => {
-                        if let (Some(len), Ok(user_index)) = (
-                            len.try_eval_usize(self.tcx, self.param_env),
-                            field.as_str().parse::<u64>()
-                        ) {
-                            let base = self.tcx.sess.source_map()
-                                .span_to_snippet(base.span)
-                                .unwrap_or_else(|_|
-                                    self.tcx.hir().hir_to_pretty_string(base.hir_id));
-                            let help = "instead of using tuple indexing, use array indexing";
-                            let suggestion = format!("{}[{}]", base, field);
-                            let applicability = if len < user_index {
-                                Applicability::MachineApplicable
-                            } else {
-                                Applicability::MaybeIncorrect
-                            };
-                            err.span_suggestion(
-                                expr.span, help, suggestion, applicability
-                            );
-                        }
+                        self.maybe_suggest_array_indexing(&mut err, expr, base, field, len);
                     }
                     ty::RawPtr(..) => {
                         let base = self.tcx.sess.source_map()
@@ -1417,7 +1399,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn ban_private_field_access(
         &self,
-        expr: &'tcx hir::Expr,
+        expr: &hir::Expr,
         expr_t: Ty<'tcx>,
         field: ast::Ident,
         base_did: DefId,
@@ -1446,7 +1428,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         err.emit();
     }
 
-    fn ban_take_value_of_method(&self, expr: &'tcx hir::Expr, expr_t: Ty<'tcx>, field: ast::Ident) {
+    fn ban_take_value_of_method(&self, expr: &hir::Expr, expr_t: Ty<'tcx>, field: ast::Ident) {
         let mut err = type_error_struct!(
             self.tcx().sess,
             field.span,
@@ -1472,6 +1454,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         err.emit();
     }
 
+    fn maybe_suggest_array_indexing(
+        &self,
+        err: &mut DiagnosticBuilder<'_>,
+        expr: &hir::Expr,
+        base: &hir::Expr,
+        field: ast::Ident,
+        len: &ty::Const<'tcx>,
+    ) {
+        if let (Some(len), Ok(user_index)) = (
+            len.try_eval_usize(self.tcx, self.param_env),
+            field.as_str().parse::<u64>()
+        ) {
+            let base = self.tcx.sess.source_map()
+                .span_to_snippet(base.span)
+                .unwrap_or_else(|_| self.tcx.hir().hir_to_pretty_string(base.hir_id));
+            let help = "instead of using tuple indexing, use array indexing";
+            let suggestion = format!("{}[{}]", base, field);
+            let applicability = if len < user_index {
+                Applicability::MachineApplicable
+            } else {
+                Applicability::MaybeIncorrect
+            };
+            err.span_suggestion(expr.span, help, suggestion, applicability);
+        }
+    }
+
     fn no_such_field_err<T: Display>(&self, span: Span, field: T, expr_t: &ty::TyS<'_>)
         -> DiagnosticBuilder<'_> {
         type_error_struct!(self.tcx().sess, span, expr_t, E0609,

From 039c78932564c38c79f08745ab6e02bceb1eb468 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Wed, 14 Aug 2019 00:31:08 +0200
Subject: [PATCH 04/35] typeck: extract suggest_first_deref_field

---
 src/librustc_typeck/check/expr.rs | 32 ++++++++++++++++++++-----------
 1 file changed, 21 insertions(+), 11 deletions(-)

diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index 20a47441375ba..2b696613c8b55 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -1373,17 +1373,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         self.maybe_suggest_array_indexing(&mut err, expr, base, field, len);
                     }
                     ty::RawPtr(..) => {
-                        let base = self.tcx.sess.source_map()
-                            .span_to_snippet(base.span)
-                            .unwrap_or_else(|_| self.tcx.hir().hir_to_pretty_string(base.hir_id));
-                        let msg = format!("`{}` is a raw pointer; try dereferencing it", base);
-                        let suggestion = format!("(*{}).{}", base, field);
-                        err.span_suggestion(
-                            expr.span,
-                            &msg,
-                            suggestion,
-                            Applicability::MaybeIncorrect,
-                        );
+                        self.suggest_first_deref_field(&mut err, expr, base, field);
                     }
                     _ => {}
                 }
@@ -1480,6 +1470,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
+    fn suggest_first_deref_field(
+        &self,
+        err: &mut DiagnosticBuilder<'_>,
+        expr: &hir::Expr,
+        base: &hir::Expr,
+        field: ast::Ident,
+    ) {
+        let base = self.tcx.sess.source_map()
+            .span_to_snippet(base.span)
+            .unwrap_or_else(|_| self.tcx.hir().hir_to_pretty_string(base.hir_id));
+        let msg = format!("`{}` is a raw pointer; try dereferencing it", base);
+        let suggestion = format!("(*{}).{}", base, field);
+        err.span_suggestion(
+            expr.span,
+            &msg,
+            suggestion,
+            Applicability::MaybeIncorrect,
+        );
+    }
+
     fn no_such_field_err<T: Display>(&self, span: Span, field: T, expr_t: &ty::TyS<'_>)
         -> DiagnosticBuilder<'_> {
         type_error_struct!(self.tcx().sess, span, expr_t, E0609,

From 01e96dc5832b85f87acb1a651e33d12ac9b37cc5 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Wed, 14 Aug 2019 00:40:44 +0200
Subject: [PATCH 05/35] typeck: extract suggest_fields_on_recordish

---
 src/librustc_typeck/check/expr.rs | 45 ++++++++++++++++++-------------
 1 file changed, 27 insertions(+), 18 deletions(-)

diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index 2b696613c8b55..e4582424d0fca 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -1350,24 +1350,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                 match expr_t.sty {
                     ty::Adt(def, _) if !def.is_enum() => {
-                        if let Some(suggested_field_name) =
-                            Self::suggest_field_name(def.non_enum_variant(),
-                                                     &field.as_str(), vec![]) {
-                                err.span_suggestion(
-                                    field.span,
-                                    "a field with a similar name exists",
-                                    suggested_field_name.to_string(),
-                                    Applicability::MaybeIncorrect,
-                                );
-                            } else {
-                                err.span_label(field.span, "unknown field");
-                                let struct_variant_def = def.non_enum_variant();
-                                let field_names = self.available_field_names(struct_variant_def);
-                                if !field_names.is_empty() {
-                                    err.note(&format!("available fields are: {}",
-                                                      self.name_series_display(field_names)));
-                                }
-                            };
+                        self.suggest_fields_on_recordish(&mut err, def, field);
                     }
                     ty::Array(_, len) => {
                         self.maybe_suggest_array_indexing(&mut err, expr, base, field, len);
@@ -1444,6 +1427,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         err.emit();
     }
 
+    fn suggest_fields_on_recordish(
+        &self,
+        err: &mut DiagnosticBuilder<'_>,
+        def: &'tcx ty::AdtDef,
+        field: ast::Ident,
+    ) {
+        if let Some(suggested_field_name) =
+            Self::suggest_field_name(def.non_enum_variant(), &field.as_str(), vec![])
+        {
+            err.span_suggestion(
+                field.span,
+                "a field with a similar name exists",
+                suggested_field_name.to_string(),
+                Applicability::MaybeIncorrect,
+            );
+        } else {
+            err.span_label(field.span, "unknown field");
+            let struct_variant_def = def.non_enum_variant();
+            let field_names = self.available_field_names(struct_variant_def);
+            if !field_names.is_empty() {
+                err.note(&format!("available fields are: {}",
+                                    self.name_series_display(field_names)));
+            }
+        }
+    }
+
     fn maybe_suggest_array_indexing(
         &self,
         err: &mut DiagnosticBuilder<'_>,

From 07414417c58cf9e1ad1d75730007c683bd7dfae7 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Wed, 14 Aug 2019 00:50:39 +0200
Subject: [PATCH 06/35] typeck: restructure check_field a bit

---
 src/librustc_typeck/check/expr.rs | 56 +++++++++++++++++--------------
 1 file changed, 31 insertions(+), 25 deletions(-)

diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index e4582424d0fca..57e82714150e8 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -1338,36 +1338,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         if let Some((did, field_ty)) = private_candidate {
             self.ban_private_field_access(expr, expr_t, field, did);
-            field_ty
-        } else if field.name == kw::Invalid {
-            self.tcx().types.err
+            return field_ty;
+        }
+
+        if field.name == kw::Invalid {
         } else if self.method_exists(field, expr_t, expr.hir_id, true) {
             self.ban_take_value_of_method(expr, expr_t, field);
-            self.tcx().types.err
-        } else {
-            if !expr_t.is_primitive_ty() {
-                let mut err = self.no_such_field_err(field.span, field, expr_t);
+        } else if !expr_t.is_primitive_ty() {
+            let mut err = self.no_such_field_err(field.span, field, expr_t);
 
-                match expr_t.sty {
-                    ty::Adt(def, _) if !def.is_enum() => {
-                        self.suggest_fields_on_recordish(&mut err, def, field);
-                    }
-                    ty::Array(_, len) => {
-                        self.maybe_suggest_array_indexing(&mut err, expr, base, field, len);
-                    }
-                    ty::RawPtr(..) => {
-                        self.suggest_first_deref_field(&mut err, expr, base, field);
-                    }
-                    _ => {}
+            match expr_t.sty {
+                ty::Adt(def, _) if !def.is_enum() => {
+                    self.suggest_fields_on_recordish(&mut err, def, field);
                 }
-                err
-            } else {
-                type_error_struct!(self.tcx().sess, field.span, expr_t, E0610,
-                                   "`{}` is a primitive type and therefore doesn't have fields",
-                                   expr_t)
-            }.emit();
-            self.tcx().types.err
+                ty::Array(_, len) => {
+                    self.maybe_suggest_array_indexing(&mut err, expr, base, field, len);
+                }
+                ty::RawPtr(..) => {
+                    self.suggest_first_deref_field(&mut err, expr, base, field);
+                }
+                _ => {}
+            }
+
+            err.emit();
+        } else {
+            type_error_struct!(
+                self.tcx().sess,
+                field.span,
+                expr_t,
+                E0610,
+                "`{}` is a primitive type and therefore doesn't have fields",
+                expr_t
+            )
+            .emit();
         }
+
+        self.tcx().types.err
     }
 
     fn ban_private_field_access(

From 88398a429c04ac915fbd314da22c6dc813c275c9 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Wed, 14 Aug 2019 01:51:41 +0200
Subject: [PATCH 07/35] typeck: on wrong <expr>.await suggest -> 2018

---
 src/librustc_typeck/check/expr.rs | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index 57e82714150e8..d139cd4264c86 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -1360,6 +1360,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 _ => {}
             }
 
+            if field.name == kw::Await {
+                // We know by construction that `<expr>.await` is either on Rust 2015
+                // or results in `ExprKind::Await`. Suggest switching the edition to 2018.
+                err.note("to `.await` a `Future`, switch to Rust 2018");
+                err.help("set `edition = \"2018\"` in `Cargo.toml`");
+                err.note("for more on editions, read https://doc.rust-lang.org/edition-guide");
+            }
+
             err.emit();
         } else {
             type_error_struct!(

From 9287eb647f7168a65950965044bd5e22d1b05faf Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Wed, 14 Aug 2019 01:52:16 +0200
Subject: [PATCH 08/35] typeck: add tests for suggesting -> 2018 on wrong
 <expr>.await

---
 .../suggest-switching-edition-on-await.rs     | 45 +++++++++++++++++++
 .../suggest-switching-edition-on-await.stderr | 43 ++++++++++++++++++
 2 files changed, 88 insertions(+)
 create mode 100644 src/test/ui/async-await/suggest-switching-edition-on-await.rs
 create mode 100644 src/test/ui/async-await/suggest-switching-edition-on-await.stderr

diff --git a/src/test/ui/async-await/suggest-switching-edition-on-await.rs b/src/test/ui/async-await/suggest-switching-edition-on-await.rs
new file mode 100644
index 0000000000000..1402f1ca92ba8
--- /dev/null
+++ b/src/test/ui/async-await/suggest-switching-edition-on-await.rs
@@ -0,0 +1,45 @@
+use std::pin::Pin;
+use std::future::Future;
+
+fn main() {}
+
+fn await_on_struct_missing() {
+    struct S;
+    let x = S;
+    x.await;
+    //~^ ERROR no field `await` on type
+    //~| NOTE unknown field
+    //~| NOTE to `.await` a `Future`, switch to Rust 2018
+    //~| HELP set `edition = "2018"` in `Cargo.toml`
+    //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
+}
+
+fn await_on_struct_similar() {
+    struct S {
+        awai: u8,
+    }
+    let x = S { awai: 42 };
+    x.await;
+    //~^ ERROR no field `await` on type
+    //~| HELP a field with a similar name exists
+    //~| NOTE to `.await` a `Future`, switch to Rust 2018
+    //~| HELP set `edition = "2018"` in `Cargo.toml`
+    //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
+}
+
+fn await_on_63533(x: Pin<&mut dyn Future<Output = ()>>) {
+    x.await;
+    //~^ ERROR no field `await` on type
+    //~| NOTE unknown field
+    //~| NOTE to `.await` a `Future`, switch to Rust 2018
+    //~| HELP set `edition = "2018"` in `Cargo.toml`
+    //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
+}
+
+fn await_on_apit(x: impl Future<Output = ()>) {
+    x.await;
+    //~^ ERROR no field `await` on type
+    //~| NOTE to `.await` a `Future`, switch to Rust 2018
+    //~| HELP set `edition = "2018"` in `Cargo.toml`
+    //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
+}
diff --git a/src/test/ui/async-await/suggest-switching-edition-on-await.stderr b/src/test/ui/async-await/suggest-switching-edition-on-await.stderr
new file mode 100644
index 0000000000000..f623511c0eb23
--- /dev/null
+++ b/src/test/ui/async-await/suggest-switching-edition-on-await.stderr
@@ -0,0 +1,43 @@
+error[E0609]: no field `await` on type `await_on_struct_missing::S`
+  --> $DIR/suggest-switching-edition-on-await.rs:9:7
+   |
+LL |     x.await;
+   |       ^^^^^ unknown field
+   |
+   = note: to `.await` a `Future`, switch to Rust 2018
+   = help: set `edition = "2018"` in `Cargo.toml`
+   = note: for more on editions, read https://doc.rust-lang.org/edition-guide
+
+error[E0609]: no field `await` on type `await_on_struct_similar::S`
+  --> $DIR/suggest-switching-edition-on-await.rs:22:7
+   |
+LL |     x.await;
+   |       ^^^^^ help: a field with a similar name exists: `awai`
+   |
+   = note: to `.await` a `Future`, switch to Rust 2018
+   = help: set `edition = "2018"` in `Cargo.toml`
+   = note: for more on editions, read https://doc.rust-lang.org/edition-guide
+
+error[E0609]: no field `await` on type `std::pin::Pin<&mut dyn std::future::Future<Output = ()>>`
+  --> $DIR/suggest-switching-edition-on-await.rs:31:7
+   |
+LL |     x.await;
+   |       ^^^^^ unknown field
+   |
+   = note: to `.await` a `Future`, switch to Rust 2018
+   = help: set `edition = "2018"` in `Cargo.toml`
+   = note: for more on editions, read https://doc.rust-lang.org/edition-guide
+
+error[E0609]: no field `await` on type `impl Future<Output = ()>`
+  --> $DIR/suggest-switching-edition-on-await.rs:40:7
+   |
+LL |     x.await;
+   |       ^^^^^
+   |
+   = note: to `.await` a `Future`, switch to Rust 2018
+   = help: set `edition = "2018"` in `Cargo.toml`
+   = note: for more on editions, read https://doc.rust-lang.org/edition-guide
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0609`.

From f54503c908413ef54ac9dc8ccf47915fa07a3286 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 15 Aug 2019 09:59:25 +0200
Subject: [PATCH 09/35] libcore: more cleanups using associated_type_bounds

---
 src/libcore/iter/adapters/flatten.rs | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/src/libcore/iter/adapters/flatten.rs b/src/libcore/iter/adapters/flatten.rs
index d8d41a2a31ef6..d812da26580bc 100644
--- a/src/libcore/iter/adapters/flatten.rs
+++ b/src/libcore/iter/adapters/flatten.rs
@@ -72,8 +72,7 @@ impl<I: Iterator, U: IntoIterator, F> Iterator for FlatMap<I, U, F>
 impl<I: DoubleEndedIterator, U, F> DoubleEndedIterator for FlatMap<I, U, F>
 where
     F: FnMut(I::Item) -> U,
-    U: IntoIterator,
-    U::IntoIter: DoubleEndedIterator,
+    U: IntoIterator<IntoIter: DoubleEndedIterator>,
 {
     #[inline]
     fn next_back(&mut self) -> Option<U::Item> { self.inner.next_back() }
@@ -107,10 +106,7 @@ impl<I, U, F> FusedIterator for FlatMap<I, U, F>
 /// [`Iterator`]: trait.Iterator.html
 #[must_use = "iterators are lazy and do nothing unless consumed"]
 #[stable(feature = "iterator_flatten", since = "1.29.0")]
-pub struct Flatten<I: Iterator>
-where
-    I::Item: IntoIterator,
-{
+pub struct Flatten<I: Iterator<Item: IntoIterator>> {
     inner: FlattenCompat<I, <I::Item as IntoIterator>::IntoIter>,
 }
 

From f036faeb3581c1079516667d43a77e2d23963c0a Mon Sep 17 00:00:00 2001
From: Kevin Per <kevin.per@protonmail.com>
Date: Thu, 15 Aug 2019 11:37:19 +0200
Subject: [PATCH 10/35] Grouping ABI test #62401

---
 .../run-pass/abi/abi-sysv64-arg-passing.rs    | 366 ++++++++++++++++++
 .../run-pass/abi/abi-sysv64-register-usage.rs |  95 +++++
 src/test/run-pass/abi/abort-on-c-abi.rs       |  36 ++
 src/test/run-pass/abi/anon-extern-mod.rs      |  17 +
 .../anon-extern-mod-cross-crate-1.rs          |   9 +
 .../run-pass/abi/auxiliary/foreign_lib.rs     |  38 ++
 src/test/run-pass/abi/c-stack-as-value.rs     |  17 +
 src/test/run-pass/abi/cabi-int-widening.rs    |  14 +
 .../anon-extern-mod-cross-crate-1.rs          |   9 +
 .../anon-extern-mod-cross-crate-1.rs          |   9 +
 .../auxiliary/extern-crosscrate-source.rs     |  31 ++
 .../run-pass/abi/extern/extern-call-deep.rs   |  39 ++
 .../run-pass/abi/extern/extern-call-deep2.rs  |  44 +++
 .../abi/extern/extern-call-indirect.rs        |  38 ++
 .../run-pass/abi/extern/extern-call-scrub.rs  |  48 +++
 .../abi/extern/extern-pass-TwoU16s.rs         |  25 ++
 .../run-pass/abi/extern/extern-pass-TwoU8s.rs |  25 ++
 .../run-pass/abi/extern/extern-pass-char.rs   |  16 +
 .../run-pass/abi/extern/extern-pass-double.rs |  13 +
 .../run-pass/abi/extern/extern-pass-empty.rs  |  55 +++
 .../abi/extern/extern-return-TwoU16s.rs       |  21 +
 .../abi/extern/extern-return-TwoU32s.rs       |  21 +
 .../abi/extern/extern-return-TwoU64s.rs       |  21 +
 .../abi/extern/extern-return-TwoU8s.rs        |  21 +
 .../abi/foreign/auxiliary/foreign_lib.rs      |  38 ++
 .../abi/foreign/foreign-call-no-runtime.rs    |  55 +++
 .../abi/foreign/foreign-fn-with-byval.rs      |  32 ++
 .../run-pass/abi/foreign/foreign-no-abi.rs    |  22 ++
 .../abi/issues/auxiliary/issue-25185-1.rs     |   8 +
 src/test/run-pass/abi/issues/issue-28676.rs   |  35 ++
 src/test/run-pass/abi/lib-defaults.rs         |  16 +
 .../run-pass/abi/macros/macros-in-extern.rs   |  30 ++
 .../abi/mir/mir_codegen_calls_variadic.rs     |  22 ++
 .../abi/numbers-arithmetic/i128-ffi.rs        |  31 ++
 .../abi/proc_macro/macros-in-extern.rs        |  24 ++
 .../abi/rfcs/rfc1717/library-override.rs      |  14 +
 .../run-pass/abi/segfault-no-out-of-stack.rs  |  48 +++
 src/test/run-pass/abi/stack-probes.rs         |  67 ++++
 .../abi/statics/static-mut-foreign.rs         |  41 ++
 .../abi/structs-enums/struct-return.rs        |  64 +++
 .../run-pass/abi/union/union-c-interop.rs     |  37 ++
 src/test/run-pass/abi/variadic-ffi.rs         |  83 ++++
 42 files changed, 1695 insertions(+)
 create mode 100644 src/test/run-pass/abi/abi-sysv64-arg-passing.rs
 create mode 100644 src/test/run-pass/abi/abi-sysv64-register-usage.rs
 create mode 100644 src/test/run-pass/abi/abort-on-c-abi.rs
 create mode 100644 src/test/run-pass/abi/anon-extern-mod.rs
 create mode 100644 src/test/run-pass/abi/auxiliary/anon-extern-mod-cross-crate-1.rs
 create mode 100644 src/test/run-pass/abi/auxiliary/foreign_lib.rs
 create mode 100644 src/test/run-pass/abi/c-stack-as-value.rs
 create mode 100644 src/test/run-pass/abi/cabi-int-widening.rs
 create mode 100644 src/test/run-pass/abi/consts/auxiliary/anon-extern-mod-cross-crate-1.rs
 create mode 100644 src/test/run-pass/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs
 create mode 100644 src/test/run-pass/abi/extern/auxiliary/extern-crosscrate-source.rs
 create mode 100644 src/test/run-pass/abi/extern/extern-call-deep.rs
 create mode 100644 src/test/run-pass/abi/extern/extern-call-deep2.rs
 create mode 100644 src/test/run-pass/abi/extern/extern-call-indirect.rs
 create mode 100644 src/test/run-pass/abi/extern/extern-call-scrub.rs
 create mode 100644 src/test/run-pass/abi/extern/extern-pass-TwoU16s.rs
 create mode 100644 src/test/run-pass/abi/extern/extern-pass-TwoU8s.rs
 create mode 100644 src/test/run-pass/abi/extern/extern-pass-char.rs
 create mode 100644 src/test/run-pass/abi/extern/extern-pass-double.rs
 create mode 100644 src/test/run-pass/abi/extern/extern-pass-empty.rs
 create mode 100644 src/test/run-pass/abi/extern/extern-return-TwoU16s.rs
 create mode 100644 src/test/run-pass/abi/extern/extern-return-TwoU32s.rs
 create mode 100644 src/test/run-pass/abi/extern/extern-return-TwoU64s.rs
 create mode 100644 src/test/run-pass/abi/extern/extern-return-TwoU8s.rs
 create mode 100644 src/test/run-pass/abi/foreign/auxiliary/foreign_lib.rs
 create mode 100644 src/test/run-pass/abi/foreign/foreign-call-no-runtime.rs
 create mode 100644 src/test/run-pass/abi/foreign/foreign-fn-with-byval.rs
 create mode 100644 src/test/run-pass/abi/foreign/foreign-no-abi.rs
 create mode 100644 src/test/run-pass/abi/issues/auxiliary/issue-25185-1.rs
 create mode 100644 src/test/run-pass/abi/issues/issue-28676.rs
 create mode 100644 src/test/run-pass/abi/lib-defaults.rs
 create mode 100644 src/test/run-pass/abi/macros/macros-in-extern.rs
 create mode 100644 src/test/run-pass/abi/mir/mir_codegen_calls_variadic.rs
 create mode 100644 src/test/run-pass/abi/numbers-arithmetic/i128-ffi.rs
 create mode 100644 src/test/run-pass/abi/proc_macro/macros-in-extern.rs
 create mode 100644 src/test/run-pass/abi/rfcs/rfc1717/library-override.rs
 create mode 100644 src/test/run-pass/abi/segfault-no-out-of-stack.rs
 create mode 100644 src/test/run-pass/abi/stack-probes.rs
 create mode 100644 src/test/run-pass/abi/statics/static-mut-foreign.rs
 create mode 100644 src/test/run-pass/abi/structs-enums/struct-return.rs
 create mode 100644 src/test/run-pass/abi/union/union-c-interop.rs
 create mode 100644 src/test/run-pass/abi/variadic-ffi.rs

diff --git a/src/test/run-pass/abi/abi-sysv64-arg-passing.rs b/src/test/run-pass/abi/abi-sysv64-arg-passing.rs
new file mode 100644
index 0000000000000..fdf0573b5e3ec
--- /dev/null
+++ b/src/test/run-pass/abi/abi-sysv64-arg-passing.rs
@@ -0,0 +1,366 @@
+// Checks if the "sysv64" calling convention behaves the same as the
+// "C" calling convention on platforms where both should be the same
+
+// This file contains versions of the following run-pass tests with
+// the calling convention changed to "sysv64"
+
+// cabi-int-widening
+// extern-pass-char
+// extern-pass-u32
+// extern-pass-u64
+// extern-pass-double
+// extern-pass-empty
+// extern-pass-TwoU8s
+// extern-pass-TwoU16s
+// extern-pass-TwoU32s
+// extern-pass-TwoU64s
+// extern-return-TwoU8s
+// extern-return-TwoU16s
+// extern-return-TwoU32s
+// extern-return-TwoU64s
+// foreign-fn-with-byval
+// issue-28676
+// issue-62350-sysv-neg-reg-counts
+// struct-return
+
+// ignore-android
+// ignore-arm
+// ignore-aarch64
+// ignore-windows
+
+// note: windows is ignored as rust_test_helpers does not have the sysv64 abi on windows
+
+#[allow(dead_code)]
+#[allow(improper_ctypes)]
+
+#[cfg(target_arch = "x86_64")]
+mod tests {
+    #[repr(C)]
+    #[derive(Copy, Clone, PartialEq, Debug)]
+    pub struct TwoU8s {
+        one: u8, two: u8
+    }
+
+    #[repr(C)]
+    #[derive(Copy, Clone, PartialEq, Debug)]
+    pub struct TwoU16s {
+        one: u16, two: u16
+    }
+
+    #[repr(C)]
+    #[derive(Copy, Clone, PartialEq, Debug)]
+    pub struct TwoU32s {
+        one: u32, two: u32
+    }
+
+    #[repr(C)]
+    #[derive(Copy, Clone, PartialEq, Debug)]
+    pub struct TwoU64s {
+        one: u64, two: u64
+    }
+
+    #[repr(C)]
+    pub struct ManyInts {
+        arg1: i8,
+        arg2: i16,
+        arg3: i32,
+        arg4: i16,
+        arg5: i8,
+        arg6: TwoU8s,
+    }
+
+    #[repr(C)]
+    pub struct Empty;
+
+    #[repr(C)]
+    #[derive(Copy, Clone)]
+    pub struct S {
+        x: u64,
+        y: u64,
+        z: u64,
+    }
+
+    #[repr(C)]
+    #[derive(Copy, Clone)]
+    pub struct Quad { a: u64, b: u64, c: u64, d: u64 }
+
+    #[derive(Copy, Clone)]
+    pub struct QuadFloats { a: f32, b: f32, c: f32, d: f32 }
+
+    #[repr(C)]
+    #[derive(Copy, Clone)]
+    pub struct Floats { a: f64, b: u8, c: f64 }
+
+    #[link(name = "rust_test_helpers", kind = "static")]
+    extern "sysv64" {
+        pub fn rust_int8_to_int32(_: i8) -> i32;
+        pub fn rust_dbg_extern_identity_u8(v: u8) -> u8;
+        pub fn rust_dbg_extern_identity_u32(v: u32) -> u32;
+        pub fn rust_dbg_extern_identity_u64(v: u64) -> u64;
+        pub fn rust_dbg_extern_identity_double(v: f64) -> f64;
+        pub fn rust_dbg_extern_empty_struct(v1: ManyInts, e: Empty, v2: ManyInts);
+        pub fn rust_dbg_extern_identity_TwoU8s(v: TwoU8s) -> TwoU8s;
+        pub fn rust_dbg_extern_identity_TwoU16s(v: TwoU16s) -> TwoU16s;
+        pub fn rust_dbg_extern_identity_TwoU32s(v: TwoU32s) -> TwoU32s;
+        pub fn rust_dbg_extern_identity_TwoU64s(v: TwoU64s) -> TwoU64s;
+        pub fn rust_dbg_extern_return_TwoU8s() -> TwoU8s;
+        pub fn rust_dbg_extern_return_TwoU16s() -> TwoU16s;
+        pub fn rust_dbg_extern_return_TwoU32s() -> TwoU32s;
+        pub fn rust_dbg_extern_return_TwoU64s() -> TwoU64s;
+        pub fn get_x(x: S) -> u64;
+        pub fn get_y(x: S) -> u64;
+        pub fn get_z(x: S) -> u64;
+        pub fn get_c_many_params(_: *const (), _: *const (),
+                                 _: *const (), _: *const (), f: Quad) -> u64;
+        pub fn get_c_exhaust_sysv64_ints(
+            _: *const (),
+            _: *const (),
+            _: *const (),
+            _: *const (),
+            _: *const (),
+            _: *const (),
+            _: *const (),
+            h: QuadFloats,
+        ) -> f32;
+        pub fn rust_dbg_abi_1(q: Quad) -> Quad;
+        pub fn rust_dbg_abi_2(f: Floats) -> Floats;
+    }
+
+    pub fn cabi_int_widening() {
+        let x = unsafe {
+            rust_int8_to_int32(-1)
+        };
+
+        assert!(x == -1);
+    }
+
+    pub fn extern_pass_char() {
+        unsafe {
+            assert_eq!(22, rust_dbg_extern_identity_u8(22));
+        }
+    }
+
+    pub fn extern_pass_u32() {
+        unsafe {
+            assert_eq!(22, rust_dbg_extern_identity_u32(22));
+        }
+    }
+
+    pub fn extern_pass_u64() {
+        unsafe {
+            assert_eq!(22, rust_dbg_extern_identity_u64(22));
+        }
+    }
+
+    pub fn extern_pass_double() {
+        unsafe {
+            assert_eq!(22.0_f64, rust_dbg_extern_identity_double(22.0_f64));
+        }
+    }
+
+    pub fn extern_pass_empty() {
+        unsafe {
+            let x = ManyInts {
+                arg1: 2,
+                arg2: 3,
+                arg3: 4,
+                arg4: 5,
+                arg5: 6,
+                arg6: TwoU8s { one: 7, two: 8, }
+            };
+            let y = ManyInts {
+                arg1: 1,
+                arg2: 2,
+                arg3: 3,
+                arg4: 4,
+                arg5: 5,
+                arg6: TwoU8s { one: 6, two: 7, }
+            };
+            let empty = Empty;
+            rust_dbg_extern_empty_struct(x, empty, y);
+        }
+    }
+
+    pub fn extern_pass_twou8s() {
+        unsafe {
+            let x = TwoU8s {one: 22, two: 23};
+            let y = rust_dbg_extern_identity_TwoU8s(x);
+            assert_eq!(x, y);
+        }
+    }
+
+    pub fn extern_pass_twou16s() {
+        unsafe {
+            let x = TwoU16s {one: 22, two: 23};
+            let y = rust_dbg_extern_identity_TwoU16s(x);
+            assert_eq!(x, y);
+        }
+    }
+
+    pub fn extern_pass_twou32s() {
+        unsafe {
+            let x = TwoU32s {one: 22, two: 23};
+            let y = rust_dbg_extern_identity_TwoU32s(x);
+            assert_eq!(x, y);
+        }
+    }
+
+    pub fn extern_pass_twou64s() {
+        unsafe {
+            let x = TwoU64s {one: 22, two: 23};
+            let y = rust_dbg_extern_identity_TwoU64s(x);
+            assert_eq!(x, y);
+        }
+    }
+
+    pub fn extern_return_twou8s() {
+        unsafe {
+            let y = rust_dbg_extern_return_TwoU8s();
+            assert_eq!(y.one, 10);
+            assert_eq!(y.two, 20);
+        }
+    }
+
+    pub fn extern_return_twou16s() {
+        unsafe {
+            let y = rust_dbg_extern_return_TwoU16s();
+            assert_eq!(y.one, 10);
+            assert_eq!(y.two, 20);
+        }
+    }
+
+    pub fn extern_return_twou32s() {
+        unsafe {
+            let y = rust_dbg_extern_return_TwoU32s();
+            assert_eq!(y.one, 10);
+            assert_eq!(y.two, 20);
+        }
+    }
+
+    pub fn extern_return_twou64s() {
+        unsafe {
+            let y = rust_dbg_extern_return_TwoU64s();
+            assert_eq!(y.one, 10);
+            assert_eq!(y.two, 20);
+        }
+    }
+
+    #[inline(never)]
+    fn indirect_call(func: unsafe extern "sysv64" fn(s: S) -> u64, s: S) -> u64 {
+        unsafe {
+            func(s)
+        }
+    }
+
+    pub fn foreign_fn_with_byval() {
+        let s = S { x: 1, y: 2, z: 3 };
+        assert_eq!(s.x, indirect_call(get_x, s));
+        assert_eq!(s.y, indirect_call(get_y, s));
+        assert_eq!(s.z, indirect_call(get_z, s));
+    }
+
+    fn test() {
+        use std::ptr;
+        unsafe {
+            let null = ptr::null();
+            let q = Quad {
+                a: 1,
+                b: 2,
+                c: 3,
+                d: 4
+            };
+            assert_eq!(get_c_many_params(null, null, null, null, q), q.c);
+        }
+    }
+
+    pub fn issue_28676() {
+        test();
+    }
+
+    fn test_62350() {
+        use std::ptr;
+        unsafe {
+            let null = ptr::null();
+            let q = QuadFloats {
+                a: 10.2,
+                b: 20.3,
+                c: 30.4,
+                d: 40.5
+            };
+            assert_eq!(
+                get_c_exhaust_sysv64_ints(null, null, null, null, null, null, null, q),
+                q.c,
+            );
+        }
+    }
+
+    pub fn issue_62350() {
+        test_62350();
+    }
+
+    fn test1() {
+        unsafe {
+            let q = Quad { a: 0xaaaa_aaaa_aaaa_aaaa,
+                     b: 0xbbbb_bbbb_bbbb_bbbb,
+                     c: 0xcccc_cccc_cccc_cccc,
+                     d: 0xdddd_dddd_dddd_dddd };
+            let qq = rust_dbg_abi_1(q);
+            println!("a: {:x}", qq.a as usize);
+            println!("b: {:x}", qq.b as usize);
+            println!("c: {:x}", qq.c as usize);
+            println!("d: {:x}", qq.d as usize);
+            assert_eq!(qq.a, q.c + 1);
+            assert_eq!(qq.b, q.d - 1);
+            assert_eq!(qq.c, q.a + 1);
+            assert_eq!(qq.d, q.b - 1);
+        }
+    }
+
+    fn test2() {
+        unsafe {
+            let f = Floats { a: 1.234567890e-15_f64,
+                     b: 0b_1010_1010,
+                     c: 1.0987654321e-15_f64 };
+            let ff = rust_dbg_abi_2(f);
+            println!("a: {}", ff.a as f64);
+            println!("b: {}", ff.b as usize);
+            println!("c: {}", ff.c as f64);
+            assert_eq!(ff.a, f.c + 1.0f64);
+            assert_eq!(ff.b, 0xff);
+            assert_eq!(ff.c, f.a - 1.0f64);
+        }
+    }
+
+    pub fn struct_return() {
+        test1();
+        test2();
+    }
+}
+
+#[cfg(target_arch = "x86_64")]
+fn main() {
+    use tests::*;
+    cabi_int_widening();
+    extern_pass_char();
+    extern_pass_u32();
+    extern_pass_u64();
+    extern_pass_double();
+    extern_pass_empty();
+    extern_pass_twou8s();
+    extern_pass_twou16s();
+    extern_pass_twou32s();
+    extern_pass_twou64s();
+    extern_return_twou8s();
+    extern_return_twou16s();
+    extern_return_twou32s();
+    extern_return_twou64s();
+    foreign_fn_with_byval();
+    issue_28676();
+    issue_62350();
+    struct_return();
+}
+
+#[cfg(not(target_arch = "x86_64"))]
+fn main() {
+
+}
diff --git a/src/test/run-pass/abi/abi-sysv64-register-usage.rs b/src/test/run-pass/abi/abi-sysv64-register-usage.rs
new file mode 100644
index 0000000000000..a0d6e968252a2
--- /dev/null
+++ b/src/test/run-pass/abi/abi-sysv64-register-usage.rs
@@ -0,0 +1,95 @@
+// Checks if the correct registers are being used to pass arguments
+// when the sysv64 ABI is specified.
+
+// ignore-android
+// ignore-arm
+// ignore-aarch64
+
+#![feature(asm)]
+
+#[cfg(target_arch = "x86_64")]
+pub extern "sysv64" fn all_the_registers(rdi: i64, rsi: i64, rdx: i64,
+                                         rcx: i64, r8 : i64, r9 : i64,
+                                         xmm0: f32, xmm1: f32, xmm2: f32,
+                                         xmm3: f32, xmm4: f32, xmm5: f32,
+                                         xmm6: f32, xmm7: f32) -> i64 {
+    assert_eq!(rdi, 1);
+    assert_eq!(rsi, 2);
+    assert_eq!(rdx, 3);
+    assert_eq!(rcx, 4);
+    assert_eq!(r8,  5);
+    assert_eq!(r9,  6);
+    assert_eq!(xmm0, 1.0f32);
+    assert_eq!(xmm1, 2.0f32);
+    assert_eq!(xmm2, 4.0f32);
+    assert_eq!(xmm3, 8.0f32);
+    assert_eq!(xmm4, 16.0f32);
+    assert_eq!(xmm5, 32.0f32);
+    assert_eq!(xmm6, 64.0f32);
+    assert_eq!(xmm7, 128.0f32);
+    42
+}
+
+// this struct contains 8 i64's, while only 6 can be passed in registers.
+#[cfg(target_arch = "x86_64")]
+#[derive(PartialEq, Eq, Debug)]
+pub struct LargeStruct(i64, i64, i64, i64, i64, i64, i64, i64);
+
+#[cfg(target_arch = "x86_64")]
+#[inline(never)]
+pub extern "sysv64" fn large_struct_by_val(mut foo: LargeStruct) -> LargeStruct {
+    foo.0 *= 1;
+    foo.1 *= 2;
+    foo.2 *= 3;
+    foo.3 *= 4;
+    foo.4 *= 5;
+    foo.5 *= 6;
+    foo.6 *= 7;
+    foo.7 *= 8;
+    foo
+}
+
+#[cfg(target_arch = "x86_64")]
+pub fn main() {
+    let result: i64;
+    unsafe {
+        asm!("mov rdi, 1;
+              mov rsi, 2;
+              mov rdx, 3;
+              mov rcx, 4;
+              mov r8,  5;
+              mov r9,  6;
+              mov eax, 0x3F800000;
+              movd xmm0, eax;
+              mov eax, 0x40000000;
+              movd xmm1, eax;
+              mov eax, 0x40800000;
+              movd xmm2, eax;
+              mov eax, 0x41000000;
+              movd xmm3, eax;
+              mov eax, 0x41800000;
+              movd xmm4, eax;
+              mov eax, 0x42000000;
+              movd xmm5, eax;
+              mov eax, 0x42800000;
+              movd xmm6, eax;
+              mov eax, 0x43000000;
+              movd xmm7, eax;
+              call r10
+              "
+            : "={rax}"(result)
+            : "{r10}"(all_the_registers as usize)
+            : "rdi", "rsi", "rdx", "rcx", "r8", "r9", "r11", "cc", "memory"
+            : "intel", "alignstack"
+        )
+    }
+    assert_eq!(result, 42);
+
+    assert_eq!(
+        large_struct_by_val(LargeStruct(1, 2, 3, 4, 5, 6, 7, 8)),
+        LargeStruct(1, 4, 9, 16, 25, 36, 49, 64)
+    );
+}
+
+#[cfg(not(target_arch = "x86_64"))]
+pub fn main() {}
diff --git a/src/test/run-pass/abi/abort-on-c-abi.rs b/src/test/run-pass/abi/abort-on-c-abi.rs
new file mode 100644
index 0000000000000..110f3eee1ef81
--- /dev/null
+++ b/src/test/run-pass/abi/abort-on-c-abi.rs
@@ -0,0 +1,36 @@
+#![allow(unused_must_use)]
+// Since we mark some ABIs as "nounwind" to LLVM, we must make sure that
+// we never unwind through them.
+
+// ignore-cloudabi no env and process
+// ignore-emscripten no processes
+// ignore-sgx no processes
+
+use std::{env, panic};
+use std::io::prelude::*;
+use std::io;
+use std::process::{Command, Stdio};
+
+extern "C" fn panic_in_ffi() {
+    panic!("Test");
+}
+
+fn test() {
+    let _ = panic::catch_unwind(|| { panic_in_ffi(); });
+    // The process should have aborted by now.
+    io::stdout().write(b"This should never be printed.\n");
+    let _ = io::stdout().flush();
+}
+
+fn main() {
+    let args: Vec<String> = env::args().collect();
+    if args.len() > 1 && args[1] == "test" {
+        return test();
+    }
+
+    let mut p = Command::new(&args[0])
+                        .stdout(Stdio::piped())
+                        .stdin(Stdio::piped())
+                        .arg("test").spawn().unwrap();
+    assert!(!p.wait().unwrap().success());
+}
diff --git a/src/test/run-pass/abi/anon-extern-mod.rs b/src/test/run-pass/abi/anon-extern-mod.rs
new file mode 100644
index 0000000000000..6d7e3f3cd5c1a
--- /dev/null
+++ b/src/test/run-pass/abi/anon-extern-mod.rs
@@ -0,0 +1,17 @@
+// pretty-expanded FIXME #23616
+// ignore-wasm32-bare no libc to test ffi with
+
+#![feature(rustc_private)]
+
+extern crate libc;
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern {
+    fn rust_get_test_int() -> libc::intptr_t;
+}
+
+pub fn main() {
+    unsafe {
+        let _ = rust_get_test_int();
+    }
+}
diff --git a/src/test/run-pass/abi/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/run-pass/abi/auxiliary/anon-extern-mod-cross-crate-1.rs
new file mode 100644
index 0000000000000..948b5e688ebcc
--- /dev/null
+++ b/src/test/run-pass/abi/auxiliary/anon-extern-mod-cross-crate-1.rs
@@ -0,0 +1,9 @@
+#![crate_name="anonexternmod"]
+#![feature(rustc_private)]
+
+extern crate libc;
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern {
+    pub fn rust_get_test_int() -> libc::intptr_t;
+}
diff --git a/src/test/run-pass/abi/auxiliary/foreign_lib.rs b/src/test/run-pass/abi/auxiliary/foreign_lib.rs
new file mode 100644
index 0000000000000..de6b0e2118a58
--- /dev/null
+++ b/src/test/run-pass/abi/auxiliary/foreign_lib.rs
@@ -0,0 +1,38 @@
+#![crate_name="foreign_lib"]
+
+#![feature(rustc_private)]
+
+pub mod rustrt {
+    extern crate libc;
+
+    #[link(name = "rust_test_helpers", kind = "static")]
+    extern {
+        pub fn rust_get_test_int() -> libc::intptr_t;
+    }
+}
+
+pub mod rustrt2 {
+    extern crate libc;
+
+    extern {
+        pub fn rust_get_test_int() -> libc::intptr_t;
+    }
+}
+
+pub mod rustrt3 {
+    // Different type, but same ABI (on all supported platforms).
+    // Ensures that we don't ICE or trigger LLVM asserts when
+    // importing the same symbol under different types.
+    // See https://github.com/rust-lang/rust/issues/32740.
+    extern {
+        pub fn rust_get_test_int() -> *const u8;
+    }
+}
+
+pub fn local_uses() {
+    unsafe {
+        let x = rustrt::rust_get_test_int();
+        assert_eq!(x, rustrt2::rust_get_test_int());
+        assert_eq!(x as *const _, rustrt3::rust_get_test_int());
+    }
+}
diff --git a/src/test/run-pass/abi/c-stack-as-value.rs b/src/test/run-pass/abi/c-stack-as-value.rs
new file mode 100644
index 0000000000000..3b997295c122a
--- /dev/null
+++ b/src/test/run-pass/abi/c-stack-as-value.rs
@@ -0,0 +1,17 @@
+// pretty-expanded FIXME #23616
+// ignore-wasm32-bare no libc to test ffi with
+
+#![feature(rustc_private)]
+
+mod rustrt {
+    extern crate libc;
+
+    #[link(name = "rust_test_helpers", kind = "static")]
+    extern {
+        pub fn rust_get_test_int() -> libc::intptr_t;
+    }
+}
+
+pub fn main() {
+    let _foo = rustrt::rust_get_test_int;
+}
diff --git a/src/test/run-pass/abi/cabi-int-widening.rs b/src/test/run-pass/abi/cabi-int-widening.rs
new file mode 100644
index 0000000000000..f6524c6a3d902
--- /dev/null
+++ b/src/test/run-pass/abi/cabi-int-widening.rs
@@ -0,0 +1,14 @@
+// ignore-wasm32-bare no libc to test ffi with
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern {
+    fn rust_int8_to_int32(_: i8) -> i32;
+}
+
+fn main() {
+    let x = unsafe {
+        rust_int8_to_int32(-1)
+    };
+
+    assert!(x == -1);
+}
diff --git a/src/test/run-pass/abi/consts/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/run-pass/abi/consts/auxiliary/anon-extern-mod-cross-crate-1.rs
new file mode 100644
index 0000000000000..948b5e688ebcc
--- /dev/null
+++ b/src/test/run-pass/abi/consts/auxiliary/anon-extern-mod-cross-crate-1.rs
@@ -0,0 +1,9 @@
+#![crate_name="anonexternmod"]
+#![feature(rustc_private)]
+
+extern crate libc;
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern {
+    pub fn rust_get_test_int() -> libc::intptr_t;
+}
diff --git a/src/test/run-pass/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/run-pass/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs
new file mode 100644
index 0000000000000..948b5e688ebcc
--- /dev/null
+++ b/src/test/run-pass/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs
@@ -0,0 +1,9 @@
+#![crate_name="anonexternmod"]
+#![feature(rustc_private)]
+
+extern crate libc;
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern {
+    pub fn rust_get_test_int() -> libc::intptr_t;
+}
diff --git a/src/test/run-pass/abi/extern/auxiliary/extern-crosscrate-source.rs b/src/test/run-pass/abi/extern/auxiliary/extern-crosscrate-source.rs
new file mode 100644
index 0000000000000..d4568d38e25c9
--- /dev/null
+++ b/src/test/run-pass/abi/extern/auxiliary/extern-crosscrate-source.rs
@@ -0,0 +1,31 @@
+#![crate_name="externcallback"]
+#![crate_type = "lib"]
+#![feature(rustc_private)]
+
+extern crate libc;
+
+pub mod rustrt {
+    extern crate libc;
+
+    #[link(name = "rust_test_helpers", kind = "static")]
+    extern {
+        pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t,
+                             data: libc::uintptr_t)
+                             -> libc::uintptr_t;
+    }
+}
+
+pub fn fact(n: libc::uintptr_t) -> libc::uintptr_t {
+    unsafe {
+        println!("n = {}", n);
+        rustrt::rust_dbg_call(cb, n)
+    }
+}
+
+pub extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
+    if data == 1 {
+        data
+    } else {
+        fact(data - 1) * data
+    }
+}
diff --git a/src/test/run-pass/abi/extern/extern-call-deep.rs b/src/test/run-pass/abi/extern/extern-call-deep.rs
new file mode 100644
index 0000000000000..81f884dada9b8
--- /dev/null
+++ b/src/test/run-pass/abi/extern/extern-call-deep.rs
@@ -0,0 +1,39 @@
+// run-pass
+// ignore-wasm32-bare no libc to test ffi with
+// ignore-emscripten blows the JS stack
+
+#![feature(rustc_private)]
+
+extern crate libc;
+
+mod rustrt {
+    extern crate libc;
+
+    #[link(name = "rust_test_helpers", kind = "static")]
+    extern {
+        pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t,
+                             data: libc::uintptr_t)
+                             -> libc::uintptr_t;
+    }
+}
+
+extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
+    if data == 1 {
+        data
+    } else {
+        count(data - 1) + 1
+    }
+}
+
+fn count(n: libc::uintptr_t) -> libc::uintptr_t {
+    unsafe {
+        println!("n = {}", n);
+        rustrt::rust_dbg_call(cb, n)
+    }
+}
+
+pub fn main() {
+    let result = count(1000);
+    println!("result = {}", result);
+    assert_eq!(result, 1000);
+}
diff --git a/src/test/run-pass/abi/extern/extern-call-deep2.rs b/src/test/run-pass/abi/extern/extern-call-deep2.rs
new file mode 100644
index 0000000000000..b31489b1e10cc
--- /dev/null
+++ b/src/test/run-pass/abi/extern/extern-call-deep2.rs
@@ -0,0 +1,44 @@
+// run-pass
+#![allow(unused_must_use)]
+// ignore-emscripten no threads support
+
+#![feature(rustc_private)]
+
+extern crate libc;
+use std::thread;
+
+mod rustrt {
+    extern crate libc;
+
+    #[link(name = "rust_test_helpers", kind = "static")]
+    extern {
+        pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t,
+                             data: libc::uintptr_t)
+                             -> libc::uintptr_t;
+    }
+}
+
+extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
+    if data == 1 {
+        data
+    } else {
+        count(data - 1) + 1
+    }
+}
+
+fn count(n: libc::uintptr_t) -> libc::uintptr_t {
+    unsafe {
+        println!("n = {}", n);
+        rustrt::rust_dbg_call(cb, n)
+    }
+}
+
+pub fn main() {
+    // Make sure we're on a thread with small Rust stacks (main currently
+    // has a large stack)
+    thread::spawn(move|| {
+        let result = count(1000);
+        println!("result = {}", result);
+        assert_eq!(result, 1000);
+    }).join();
+}
diff --git a/src/test/run-pass/abi/extern/extern-call-indirect.rs b/src/test/run-pass/abi/extern/extern-call-indirect.rs
new file mode 100644
index 0000000000000..158b54e4b8cdd
--- /dev/null
+++ b/src/test/run-pass/abi/extern/extern-call-indirect.rs
@@ -0,0 +1,38 @@
+// run-pass
+// ignore-wasm32-bare no libc to test ffi with
+
+#![feature(rustc_private)]
+
+extern crate libc;
+
+mod rustrt {
+    extern crate libc;
+
+    #[link(name = "rust_test_helpers", kind = "static")]
+    extern {
+        pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t,
+                             data: libc::uintptr_t)
+                             -> libc::uintptr_t;
+    }
+}
+
+extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
+    if data == 1 {
+        data
+    } else {
+        fact(data - 1) * data
+    }
+}
+
+fn fact(n: libc::uintptr_t) -> libc::uintptr_t {
+    unsafe {
+        println!("n = {}", n);
+        rustrt::rust_dbg_call(cb, n)
+    }
+}
+
+pub fn main() {
+    let result = fact(10);
+    println!("result = {}", result);
+    assert_eq!(result, 3628800);
+}
diff --git a/src/test/run-pass/abi/extern/extern-call-scrub.rs b/src/test/run-pass/abi/extern/extern-call-scrub.rs
new file mode 100644
index 0000000000000..a7b1065c9e1f6
--- /dev/null
+++ b/src/test/run-pass/abi/extern/extern-call-scrub.rs
@@ -0,0 +1,48 @@
+// run-pass
+#![allow(unused_must_use)]
+// This time we're testing repeatedly going up and down both stacks to
+// make sure the stack pointers are maintained properly in both
+// directions
+
+// ignore-emscripten no threads support
+
+#![feature(rustc_private)]
+
+extern crate libc;
+use std::thread;
+
+mod rustrt {
+    extern crate libc;
+
+    #[link(name = "rust_test_helpers", kind = "static")]
+    extern {
+        pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t,
+                             data: libc::uintptr_t)
+                             -> libc::uintptr_t;
+    }
+}
+
+extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
+    if data == 1 {
+        data
+    } else {
+        count(data - 1) + count(data - 1)
+    }
+}
+
+fn count(n: libc::uintptr_t) -> libc::uintptr_t {
+    unsafe {
+        println!("n = {}", n);
+        rustrt::rust_dbg_call(cb, n)
+    }
+}
+
+pub fn main() {
+    // Make sure we're on a thread with small Rust stacks (main currently
+    // has a large stack)
+    thread::spawn(move|| {
+        let result = count(12);
+        println!("result = {}", result);
+        assert_eq!(result, 2048);
+    }).join();
+}
diff --git a/src/test/run-pass/abi/extern/extern-pass-TwoU16s.rs b/src/test/run-pass/abi/extern/extern-pass-TwoU16s.rs
new file mode 100644
index 0000000000000..285bce2e19c31
--- /dev/null
+++ b/src/test/run-pass/abi/extern/extern-pass-TwoU16s.rs
@@ -0,0 +1,25 @@
+// run-pass
+#![allow(improper_ctypes)]
+
+// ignore-wasm32-bare no libc for ffi testing
+
+// Test a foreign function that accepts and returns a struct
+// by value.
+
+#[derive(Copy, Clone, PartialEq, Debug)]
+pub struct TwoU16s {
+    one: u16, two: u16
+}
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern {
+    pub fn rust_dbg_extern_identity_TwoU16s(v: TwoU16s) -> TwoU16s;
+}
+
+pub fn main() {
+    unsafe {
+        let x = TwoU16s {one: 22, two: 23};
+        let y = rust_dbg_extern_identity_TwoU16s(x);
+        assert_eq!(x, y);
+    }
+}
diff --git a/src/test/run-pass/abi/extern/extern-pass-TwoU8s.rs b/src/test/run-pass/abi/extern/extern-pass-TwoU8s.rs
new file mode 100644
index 0000000000000..53a6a0f29f8a6
--- /dev/null
+++ b/src/test/run-pass/abi/extern/extern-pass-TwoU8s.rs
@@ -0,0 +1,25 @@
+// run-pass
+#![allow(improper_ctypes)]
+
+// ignore-wasm32-bare no libc for ffi testing
+
+// Test a foreign function that accepts and returns a struct
+// by value.
+
+#[derive(Copy, Clone, PartialEq, Debug)]
+pub struct TwoU8s {
+    one: u8, two: u8
+}
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern {
+    pub fn rust_dbg_extern_identity_TwoU8s(v: TwoU8s) -> TwoU8s;
+}
+
+pub fn main() {
+    unsafe {
+        let x = TwoU8s {one: 22, two: 23};
+        let y = rust_dbg_extern_identity_TwoU8s(x);
+        assert_eq!(x, y);
+    }
+}
diff --git a/src/test/run-pass/abi/extern/extern-pass-char.rs b/src/test/run-pass/abi/extern/extern-pass-char.rs
new file mode 100644
index 0000000000000..22f841b45527e
--- /dev/null
+++ b/src/test/run-pass/abi/extern/extern-pass-char.rs
@@ -0,0 +1,16 @@
+// run-pass
+// ignore-wasm32-bare no libc for ffi testing
+
+// Test a function that takes/returns a u8.
+
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern {
+    pub fn rust_dbg_extern_identity_u8(v: u8) -> u8;
+}
+
+pub fn main() {
+    unsafe {
+        assert_eq!(22, rust_dbg_extern_identity_u8(22));
+    }
+}
diff --git a/src/test/run-pass/abi/extern/extern-pass-double.rs b/src/test/run-pass/abi/extern/extern-pass-double.rs
new file mode 100644
index 0000000000000..dbd0a2dfa4889
--- /dev/null
+++ b/src/test/run-pass/abi/extern/extern-pass-double.rs
@@ -0,0 +1,13 @@
+// run-pass
+// ignore-wasm32-bare no libc for ffi testing
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern {
+    pub fn rust_dbg_extern_identity_double(v: f64) -> f64;
+}
+
+pub fn main() {
+    unsafe {
+        assert_eq!(22.0_f64, rust_dbg_extern_identity_double(22.0_f64));
+    }
+}
diff --git a/src/test/run-pass/abi/extern/extern-pass-empty.rs b/src/test/run-pass/abi/extern/extern-pass-empty.rs
new file mode 100644
index 0000000000000..07099a2420483
--- /dev/null
+++ b/src/test/run-pass/abi/extern/extern-pass-empty.rs
@@ -0,0 +1,55 @@
+// run-pass
+#![allow(improper_ctypes)] // FIXME: this test is inherently not FFI-safe.
+
+// Test a foreign function that accepts empty struct.
+
+// pretty-expanded FIXME #23616
+// ignore-msvc
+// ignore-emscripten emcc asserts on an empty struct as an argument
+
+#[repr(C)]
+struct TwoU8s {
+    one: u8,
+    two: u8,
+}
+
+#[repr(C)]
+struct ManyInts {
+    arg1: i8,
+    arg2: i16,
+    arg3: i32,
+    arg4: i16,
+    arg5: i8,
+    arg6: TwoU8s,
+}
+
+#[repr(C)]
+struct Empty;
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern {
+    fn rust_dbg_extern_empty_struct(v1: ManyInts, e: Empty, v2: ManyInts);
+}
+
+pub fn main() {
+    unsafe {
+        let x = ManyInts {
+            arg1: 2,
+            arg2: 3,
+            arg3: 4,
+            arg4: 5,
+            arg5: 6,
+            arg6: TwoU8s { one: 7, two: 8, }
+        };
+        let y = ManyInts {
+            arg1: 1,
+            arg2: 2,
+            arg3: 3,
+            arg4: 4,
+            arg5: 5,
+            arg6: TwoU8s { one: 6, two: 7, }
+        };
+        let empty = Empty;
+        rust_dbg_extern_empty_struct(x, empty, y);
+    }
+}
diff --git a/src/test/run-pass/abi/extern/extern-return-TwoU16s.rs b/src/test/run-pass/abi/extern/extern-return-TwoU16s.rs
new file mode 100644
index 0000000000000..dd884ee77fe77
--- /dev/null
+++ b/src/test/run-pass/abi/extern/extern-return-TwoU16s.rs
@@ -0,0 +1,21 @@
+// run-pass
+#![allow(improper_ctypes)]
+
+// ignore-wasm32-bare no libc to test ffi with
+
+pub struct TwoU16s {
+    one: u16, two: u16
+}
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern {
+    pub fn rust_dbg_extern_return_TwoU16s() -> TwoU16s;
+}
+
+pub fn main() {
+    unsafe {
+        let y = rust_dbg_extern_return_TwoU16s();
+        assert_eq!(y.one, 10);
+        assert_eq!(y.two, 20);
+    }
+}
diff --git a/src/test/run-pass/abi/extern/extern-return-TwoU32s.rs b/src/test/run-pass/abi/extern/extern-return-TwoU32s.rs
new file mode 100644
index 0000000000000..d6aaf5c9eaf1b
--- /dev/null
+++ b/src/test/run-pass/abi/extern/extern-return-TwoU32s.rs
@@ -0,0 +1,21 @@
+// run-pass
+#![allow(improper_ctypes)]
+
+// ignore-wasm32-bare no libc to test ffi with
+
+pub struct TwoU32s {
+    one: u32, two: u32
+}
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern {
+    pub fn rust_dbg_extern_return_TwoU32s() -> TwoU32s;
+}
+
+pub fn main() {
+    unsafe {
+        let y = rust_dbg_extern_return_TwoU32s();
+        assert_eq!(y.one, 10);
+        assert_eq!(y.two, 20);
+    }
+}
diff --git a/src/test/run-pass/abi/extern/extern-return-TwoU64s.rs b/src/test/run-pass/abi/extern/extern-return-TwoU64s.rs
new file mode 100644
index 0000000000000..c5e4ebadc182a
--- /dev/null
+++ b/src/test/run-pass/abi/extern/extern-return-TwoU64s.rs
@@ -0,0 +1,21 @@
+// run-pass
+#![allow(improper_ctypes)]
+
+// ignore-wasm32-bare no libc to test ffi with
+
+pub struct TwoU64s {
+    one: u64, two: u64
+}
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern {
+    pub fn rust_dbg_extern_return_TwoU64s() -> TwoU64s;
+}
+
+pub fn main() {
+    unsafe {
+        let y = rust_dbg_extern_return_TwoU64s();
+        assert_eq!(y.one, 10);
+        assert_eq!(y.two, 20);
+    }
+}
diff --git a/src/test/run-pass/abi/extern/extern-return-TwoU8s.rs b/src/test/run-pass/abi/extern/extern-return-TwoU8s.rs
new file mode 100644
index 0000000000000..a7cd21b207359
--- /dev/null
+++ b/src/test/run-pass/abi/extern/extern-return-TwoU8s.rs
@@ -0,0 +1,21 @@
+// run-pass
+#![allow(improper_ctypes)]
+
+// ignore-wasm32-bare no libc to test ffi with
+
+pub struct TwoU8s {
+    one: u8, two: u8
+}
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern {
+    pub fn rust_dbg_extern_return_TwoU8s() -> TwoU8s;
+}
+
+pub fn main() {
+    unsafe {
+        let y = rust_dbg_extern_return_TwoU8s();
+        assert_eq!(y.one, 10);
+        assert_eq!(y.two, 20);
+    }
+}
diff --git a/src/test/run-pass/abi/foreign/auxiliary/foreign_lib.rs b/src/test/run-pass/abi/foreign/auxiliary/foreign_lib.rs
new file mode 100644
index 0000000000000..de6b0e2118a58
--- /dev/null
+++ b/src/test/run-pass/abi/foreign/auxiliary/foreign_lib.rs
@@ -0,0 +1,38 @@
+#![crate_name="foreign_lib"]
+
+#![feature(rustc_private)]
+
+pub mod rustrt {
+    extern crate libc;
+
+    #[link(name = "rust_test_helpers", kind = "static")]
+    extern {
+        pub fn rust_get_test_int() -> libc::intptr_t;
+    }
+}
+
+pub mod rustrt2 {
+    extern crate libc;
+
+    extern {
+        pub fn rust_get_test_int() -> libc::intptr_t;
+    }
+}
+
+pub mod rustrt3 {
+    // Different type, but same ABI (on all supported platforms).
+    // Ensures that we don't ICE or trigger LLVM asserts when
+    // importing the same symbol under different types.
+    // See https://github.com/rust-lang/rust/issues/32740.
+    extern {
+        pub fn rust_get_test_int() -> *const u8;
+    }
+}
+
+pub fn local_uses() {
+    unsafe {
+        let x = rustrt::rust_get_test_int();
+        assert_eq!(x, rustrt2::rust_get_test_int());
+        assert_eq!(x as *const _, rustrt3::rust_get_test_int());
+    }
+}
diff --git a/src/test/run-pass/abi/foreign/foreign-call-no-runtime.rs b/src/test/run-pass/abi/foreign/foreign-call-no-runtime.rs
new file mode 100644
index 0000000000000..c6afa07ad0503
--- /dev/null
+++ b/src/test/run-pass/abi/foreign/foreign-call-no-runtime.rs
@@ -0,0 +1,55 @@
+// run-pass
+// ignore-emscripten no threads support
+
+#![feature(rustc_private)]
+
+extern crate libc;
+
+use std::mem;
+use std::thread;
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern {
+    fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t),
+                     data: libc::uintptr_t) -> libc::uintptr_t;
+}
+
+pub fn main() {
+    unsafe {
+        thread::spawn(move|| {
+            let i: isize = 100;
+            rust_dbg_call(callback_isize, mem::transmute(&i));
+        }).join().unwrap();
+
+        thread::spawn(move|| {
+            let i: i32 = 100;
+            rust_dbg_call(callback_i32, mem::transmute(&i));
+        }).join().unwrap();
+
+        thread::spawn(move|| {
+            let i: i64 = 100;
+            rust_dbg_call(callback_i64, mem::transmute(&i));
+        }).join().unwrap();
+    }
+}
+
+extern fn callback_isize(data: libc::uintptr_t) {
+    unsafe {
+        let data: *const isize = mem::transmute(data);
+        assert_eq!(*data, 100);
+    }
+}
+
+extern fn callback_i64(data: libc::uintptr_t) {
+    unsafe {
+        let data: *const i64 = mem::transmute(data);
+        assert_eq!(*data, 100);
+    }
+}
+
+extern fn callback_i32(data: libc::uintptr_t) {
+    unsafe {
+        let data: *const i32 = mem::transmute(data);
+        assert_eq!(*data, 100);
+    }
+}
diff --git a/src/test/run-pass/abi/foreign/foreign-fn-with-byval.rs b/src/test/run-pass/abi/foreign/foreign-fn-with-byval.rs
new file mode 100644
index 0000000000000..3a35599aa573f
--- /dev/null
+++ b/src/test/run-pass/abi/foreign/foreign-fn-with-byval.rs
@@ -0,0 +1,32 @@
+// run-pass
+#![allow(improper_ctypes)]
+
+// ignore-wasm32-bare no libc to test ffi with
+
+#[derive(Copy, Clone)]
+pub struct S {
+    x: u64,
+    y: u64,
+    z: u64,
+}
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern {
+    pub fn get_x(x: S) -> u64;
+    pub fn get_y(x: S) -> u64;
+    pub fn get_z(x: S) -> u64;
+}
+
+#[inline(never)]
+fn indirect_call(func: unsafe extern fn(s: S) -> u64, s: S) -> u64 {
+    unsafe {
+        func(s)
+    }
+}
+
+fn main() {
+    let s = S { x: 1, y: 2, z: 3 };
+    assert_eq!(s.x, indirect_call(get_x, s));
+    assert_eq!(s.y, indirect_call(get_y, s));
+    assert_eq!(s.z, indirect_call(get_z, s));
+}
diff --git a/src/test/run-pass/abi/foreign/foreign-no-abi.rs b/src/test/run-pass/abi/foreign/foreign-no-abi.rs
new file mode 100644
index 0000000000000..2f33fb4765690
--- /dev/null
+++ b/src/test/run-pass/abi/foreign/foreign-no-abi.rs
@@ -0,0 +1,22 @@
+// run-pass
+// ABI is cdecl by default
+
+// ignore-wasm32-bare no libc to test ffi with
+// pretty-expanded FIXME #23616
+
+#![feature(rustc_private)]
+
+mod rustrt {
+    extern crate libc;
+
+    #[link(name = "rust_test_helpers", kind = "static")]
+    extern {
+        pub fn rust_get_test_int() -> libc::intptr_t;
+    }
+}
+
+pub fn main() {
+    unsafe {
+        rustrt::rust_get_test_int();
+    }
+}
diff --git a/src/test/run-pass/abi/issues/auxiliary/issue-25185-1.rs b/src/test/run-pass/abi/issues/auxiliary/issue-25185-1.rs
new file mode 100644
index 0000000000000..77a4787ba943d
--- /dev/null
+++ b/src/test/run-pass/abi/issues/auxiliary/issue-25185-1.rs
@@ -0,0 +1,8 @@
+// no-prefer-dynamic
+
+#![crate_type = "rlib"]
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern {
+    pub fn rust_dbg_extern_identity_u32(u: u32) -> u32;
+}
diff --git a/src/test/run-pass/abi/issues/issue-28676.rs b/src/test/run-pass/abi/issues/issue-28676.rs
new file mode 100644
index 0000000000000..2b83478ca6115
--- /dev/null
+++ b/src/test/run-pass/abi/issues/issue-28676.rs
@@ -0,0 +1,35 @@
+// run-pass
+#![allow(dead_code)]
+#![allow(improper_ctypes)]
+
+// ignore-wasm32-bare no libc to test ffi with
+
+#[derive(Copy, Clone)]
+pub struct Quad { a: u64, b: u64, c: u64, d: u64 }
+
+mod rustrt {
+    use super::Quad;
+
+    #[link(name = "rust_test_helpers", kind = "static")]
+    extern {
+        pub fn get_c_many_params(_: *const (), _: *const (),
+                                 _: *const (), _: *const (), f: Quad) -> u64;
+    }
+}
+
+fn test() {
+    unsafe {
+        let null = std::ptr::null();
+        let q = Quad {
+            a: 1,
+            b: 2,
+            c: 3,
+            d: 4
+        };
+        assert_eq!(rustrt::get_c_many_params(null, null, null, null, q), q.c);
+    }
+}
+
+pub fn main() {
+    test();
+}
diff --git a/src/test/run-pass/abi/lib-defaults.rs b/src/test/run-pass/abi/lib-defaults.rs
new file mode 100644
index 0000000000000..dcf537866c50b
--- /dev/null
+++ b/src/test/run-pass/abi/lib-defaults.rs
@@ -0,0 +1,16 @@
+// dont-check-compiler-stderr (rust-lang/rust#54222)
+
+// ignore-wasm32-bare no libc to test ffi with
+
+// compile-flags: -lrust_test_helpers
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern "C" {
+    pub fn rust_dbg_extern_identity_u32(x: u32) -> u32;
+}
+
+fn main() {
+    unsafe {
+        rust_dbg_extern_identity_u32(42);
+    }
+}
diff --git a/src/test/run-pass/abi/macros/macros-in-extern.rs b/src/test/run-pass/abi/macros/macros-in-extern.rs
new file mode 100644
index 0000000000000..28abef5cf4edc
--- /dev/null
+++ b/src/test/run-pass/abi/macros/macros-in-extern.rs
@@ -0,0 +1,30 @@
+// run-pass
+// ignore-wasm32
+
+#![feature(decl_macro, macros_in_extern)]
+
+macro_rules! returns_isize(
+    ($ident:ident) => (
+        fn $ident() -> isize;
+    )
+);
+
+macro takes_u32_returns_u32($ident:ident) {
+    fn $ident (arg: u32) -> u32;
+}
+
+macro_rules! emits_nothing(
+    () => ()
+);
+
+fn main() {
+    assert_eq!(unsafe { rust_get_test_int() }, 1isize);
+    assert_eq!(unsafe { rust_dbg_extern_identity_u32(0xDEADBEEF) }, 0xDEADBEEFu32);
+}
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern {
+    returns_isize!(rust_get_test_int);
+    takes_u32_returns_u32!(rust_dbg_extern_identity_u32);
+    emits_nothing!();
+}
diff --git a/src/test/run-pass/abi/mir/mir_codegen_calls_variadic.rs b/src/test/run-pass/abi/mir/mir_codegen_calls_variadic.rs
new file mode 100644
index 0000000000000..dc9fee03b776c
--- /dev/null
+++ b/src/test/run-pass/abi/mir/mir_codegen_calls_variadic.rs
@@ -0,0 +1,22 @@
+// run-pass
+// ignore-wasm32-bare no libc to test ffi with
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern {
+    fn rust_interesting_average(_: i64, ...) -> f64;
+}
+
+fn test<T, U>(a: i64, b: i64, c: i64, d: i64, e: i64, f: T, g: U) -> i64 {
+    unsafe {
+        rust_interesting_average(6, a, a as f64,
+                                    b, b as f64,
+                                    c, c as f64,
+                                    d, d as f64,
+                                    e, e as f64,
+                                    f, g) as i64
+    }
+}
+
+fn main(){
+    assert_eq!(test(10, 20, 30, 40, 50, 60_i64, 60.0_f64), 70);
+}
diff --git a/src/test/run-pass/abi/numbers-arithmetic/i128-ffi.rs b/src/test/run-pass/abi/numbers-arithmetic/i128-ffi.rs
new file mode 100644
index 0000000000000..19edf9779f35e
--- /dev/null
+++ b/src/test/run-pass/abi/numbers-arithmetic/i128-ffi.rs
@@ -0,0 +1,31 @@
+// run-pass
+#![allow(improper_ctypes)]
+
+// MSVC doesn't support 128 bit integers, and other Windows
+// C compilers have very inconsistent views on how the ABI
+// should look like.
+
+// ignore-windows
+// ignore-32bit
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern "C" {
+    fn identity(f: u128) -> u128;
+    fn square(f: i128) -> i128;
+    fn sub(f: i128, f: i128) -> i128;
+}
+
+fn main() {
+    unsafe {
+        let a = 0x734C_C2F2_A521;
+        let b = 0x33EE_0E2A_54E2_59DA_A0E7_8E41;
+        let b_out = identity(b);
+        assert_eq!(b, b_out);
+        let a_square = square(a);
+        assert_eq!(b, a_square as u128);
+        let k = 0x1234_5678_9ABC_DEFF_EDCB_A987_6543_210;
+        let k_d = 0x2468_ACF1_3579_BDFF_DB97_530E_CA86_420;
+        let k_out = sub(k_d, k);
+        assert_eq!(k, k_out);
+    }
+}
diff --git a/src/test/run-pass/abi/proc_macro/macros-in-extern.rs b/src/test/run-pass/abi/proc_macro/macros-in-extern.rs
new file mode 100644
index 0000000000000..99e3f7d14fd16
--- /dev/null
+++ b/src/test/run-pass/abi/proc_macro/macros-in-extern.rs
@@ -0,0 +1,24 @@
+// aux-build:test-macros.rs
+// ignore-wasm32
+
+#![feature(macros_in_extern)]
+
+extern crate test_macros;
+
+use test_macros::{nop_attr, no_output, emit_input};
+
+fn main() {
+    assert_eq!(unsafe { rust_get_test_int() }, 1isize);
+    assert_eq!(unsafe { rust_dbg_extern_identity_u32(0xDEADBEEF) }, 0xDEADBEEF);
+}
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern {
+    #[no_output]
+    fn some_definitely_unknown_symbol_which_should_be_removed();
+
+    #[nop_attr]
+    fn rust_get_test_int() -> isize;
+
+    emit_input!(fn rust_dbg_extern_identity_u32(arg: u32) -> u32;);
+}
diff --git a/src/test/run-pass/abi/rfcs/rfc1717/library-override.rs b/src/test/run-pass/abi/rfcs/rfc1717/library-override.rs
new file mode 100644
index 0000000000000..014ccac31b7a5
--- /dev/null
+++ b/src/test/run-pass/abi/rfcs/rfc1717/library-override.rs
@@ -0,0 +1,14 @@
+// run-pass
+// ignore-wasm32-bare no libc to test ffi with
+// compile-flags: -lstatic=wronglibrary:rust_test_helpers
+
+#[link(name = "wronglibrary", kind = "dylib")]
+extern "C" {
+    pub fn rust_dbg_extern_identity_u32(x: u32) -> u32;
+}
+
+fn main() {
+    unsafe {
+        rust_dbg_extern_identity_u32(42);
+    }
+}
diff --git a/src/test/run-pass/abi/segfault-no-out-of-stack.rs b/src/test/run-pass/abi/segfault-no-out-of-stack.rs
new file mode 100644
index 0000000000000..e90efface687b
--- /dev/null
+++ b/src/test/run-pass/abi/segfault-no-out-of-stack.rs
@@ -0,0 +1,48 @@
+#![allow(unused_imports)]
+// ignore-cloudabi can't run commands
+// ignore-emscripten can't run commands
+// ignore-sgx no processes
+
+#![feature(rustc_private)]
+
+extern crate libc;
+
+use std::process::{Command, ExitStatus};
+use std::env;
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern {
+    fn rust_get_null_ptr() -> *mut ::libc::c_char;
+}
+
+#[cfg(unix)]
+fn check_status(status: std::process::ExitStatus)
+{
+    use libc;
+    use std::os::unix::process::ExitStatusExt;
+
+    assert!(status.signal() == Some(libc::SIGSEGV)
+            || status.signal() == Some(libc::SIGBUS));
+}
+
+#[cfg(not(unix))]
+fn check_status(status: std::process::ExitStatus)
+{
+    assert!(!status.success());
+}
+
+fn main() {
+    let args: Vec<String> = env::args().collect();
+    if args.len() > 1 && args[1] == "segfault" {
+        unsafe { *rust_get_null_ptr() = 1; }; // trigger a segfault
+    } else {
+        let segfault = Command::new(&args[0]).arg("segfault").output().unwrap();
+        let stderr = String::from_utf8_lossy(&segfault.stderr);
+        let stdout = String::from_utf8_lossy(&segfault.stdout);
+        println!("stdout: {}", stdout);
+        println!("stderr: {}", stderr);
+        println!("status: {}", segfault.status);
+        check_status(segfault.status);
+        assert!(!stderr.contains("has overflowed its stack"));
+    }
+}
diff --git a/src/test/run-pass/abi/stack-probes.rs b/src/test/run-pass/abi/stack-probes.rs
new file mode 100644
index 0000000000000..773d0ace90ed9
--- /dev/null
+++ b/src/test/run-pass/abi/stack-probes.rs
@@ -0,0 +1,67 @@
+// ignore-arm
+// ignore-aarch64
+// ignore-mips
+// ignore-mips64
+// ignore-powerpc
+// ignore-s390x
+// ignore-sparc
+// ignore-sparc64
+// ignore-wasm
+// ignore-cloudabi no processes
+// ignore-emscripten no processes
+// ignore-sgx no processes
+// ignore-musl FIXME #31506
+
+use std::mem;
+use std::process::Command;
+use std::thread;
+use std::env;
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern {
+    #[link_name = "rust_dbg_extern_identity_u64"]
+    fn black_box(u: u64);
+}
+
+fn main() {
+    let args = env::args().skip(1).collect::<Vec<_>>();
+    if args.len() > 0 {
+        match &args[0][..] {
+            "main-thread" => recurse(&[]),
+            "child-thread" => thread::spawn(|| recurse(&[])).join().unwrap(),
+            _ => panic!(),
+        }
+        return
+    }
+
+    let me = env::current_exe().unwrap();
+
+    // The linux kernel has some different behavior for the main thread because
+    // the main thread's stack can typically grow. We can't always guarantee
+    // that we report stack overflow on the main thread, see #43052 for some
+    // details
+    if cfg!(not(target_os = "linux")) {
+        assert_overflow(Command::new(&me).arg("main-thread"));
+    }
+    assert_overflow(Command::new(&me).arg("child-thread"));
+}
+
+#[allow(unconditional_recursion)]
+fn recurse(array: &[u64]) {
+    unsafe { black_box(array.as_ptr() as u64); }
+    #[allow(deprecated)]
+    let local: [_; 1024] = unsafe { mem::uninitialized() };
+    recurse(&local);
+}
+
+fn assert_overflow(cmd: &mut Command) {
+    let output = cmd.output().unwrap();
+    assert!(!output.status.success());
+    let stdout = String::from_utf8_lossy(&output.stdout);
+    let stderr = String::from_utf8_lossy(&output.stderr);
+    println!("status: {}", output.status);
+    println!("stdout: {}", stdout);
+    println!("stderr: {}", stderr);
+    assert!(stdout.is_empty());
+    assert!(stderr.contains("has overflowed its stack\n"));
+}
diff --git a/src/test/run-pass/abi/statics/static-mut-foreign.rs b/src/test/run-pass/abi/statics/static-mut-foreign.rs
new file mode 100644
index 0000000000000..5d6fa416b9895
--- /dev/null
+++ b/src/test/run-pass/abi/statics/static-mut-foreign.rs
@@ -0,0 +1,41 @@
+// run-pass
+// Constants (static variables) can be used to match in patterns, but mutable
+// statics cannot. This ensures that there's some form of error if this is
+// attempted.
+
+// ignore-wasm32-bare no libc to test ffi with
+
+#![feature(rustc_private)]
+
+extern crate libc;
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern {
+    static mut rust_dbg_static_mut: libc::c_int;
+    pub fn rust_dbg_static_mut_check_four();
+}
+
+unsafe fn static_bound(_: &'static libc::c_int) {}
+
+fn static_bound_set(a: &'static mut libc::c_int) {
+    *a = 3;
+}
+
+unsafe fn run() {
+    assert_eq!(rust_dbg_static_mut, 3);
+    rust_dbg_static_mut = 4;
+    assert_eq!(rust_dbg_static_mut, 4);
+    rust_dbg_static_mut_check_four();
+    rust_dbg_static_mut += 1;
+    assert_eq!(rust_dbg_static_mut, 5);
+    rust_dbg_static_mut *= 3;
+    assert_eq!(rust_dbg_static_mut, 15);
+    rust_dbg_static_mut = -3;
+    assert_eq!(rust_dbg_static_mut, -3);
+    static_bound(&rust_dbg_static_mut);
+    static_bound_set(&mut rust_dbg_static_mut);
+}
+
+pub fn main() {
+    unsafe { run() }
+}
diff --git a/src/test/run-pass/abi/structs-enums/struct-return.rs b/src/test/run-pass/abi/structs-enums/struct-return.rs
new file mode 100644
index 0000000000000..5930fc4acbbe3
--- /dev/null
+++ b/src/test/run-pass/abi/structs-enums/struct-return.rs
@@ -0,0 +1,64 @@
+// run-pass
+#![allow(dead_code)]
+// ignore-wasm32-bare no libc to test ffi with
+
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct Quad { a: u64, b: u64, c: u64, d: u64 }
+
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct Floats { a: f64, b: u8, c: f64 }
+
+mod rustrt {
+    use super::{Floats, Quad};
+
+    #[link(name = "rust_test_helpers", kind = "static")]
+    extern {
+        pub fn rust_dbg_abi_1(q: Quad) -> Quad;
+        pub fn rust_dbg_abi_2(f: Floats) -> Floats;
+    }
+}
+
+fn test1() {
+    unsafe {
+        let q = Quad { a: 0xaaaa_aaaa_aaaa_aaaa,
+                 b: 0xbbbb_bbbb_bbbb_bbbb,
+                 c: 0xcccc_cccc_cccc_cccc,
+                 d: 0xdddd_dddd_dddd_dddd };
+        let qq = rustrt::rust_dbg_abi_1(q);
+        println!("a: {:x}", qq.a as usize);
+        println!("b: {:x}", qq.b as usize);
+        println!("c: {:x}", qq.c as usize);
+        println!("d: {:x}", qq.d as usize);
+        assert_eq!(qq.a, q.c + 1);
+        assert_eq!(qq.b, q.d - 1);
+        assert_eq!(qq.c, q.a + 1);
+        assert_eq!(qq.d, q.b - 1);
+    }
+}
+
+#[cfg(target_pointer_width = "64")]
+fn test2() {
+    unsafe {
+        let f = Floats { a: 1.234567890e-15_f64,
+                 b: 0b_1010_1010,
+                 c: 1.0987654321e-15_f64 };
+        let ff = rustrt::rust_dbg_abi_2(f);
+        println!("a: {}", ff.a as f64);
+        println!("b: {}", ff.b as usize);
+        println!("c: {}", ff.c as f64);
+        assert_eq!(ff.a, f.c + 1.0f64);
+        assert_eq!(ff.b, 0xff);
+        assert_eq!(ff.c, f.a - 1.0f64);
+    }
+}
+
+#[cfg(target_pointer_width = "32")]
+fn test2() {
+}
+
+pub fn main() {
+    test1();
+    test2();
+}
diff --git a/src/test/run-pass/abi/union/union-c-interop.rs b/src/test/run-pass/abi/union/union-c-interop.rs
new file mode 100644
index 0000000000000..00f04d5b7ff3d
--- /dev/null
+++ b/src/test/run-pass/abi/union/union-c-interop.rs
@@ -0,0 +1,37 @@
+// run-pass
+#![allow(non_snake_case)]
+
+// ignore-wasm32-bare no libc to test ffi with
+
+#[derive(Clone, Copy)]
+#[repr(C)]
+struct LARGE_INTEGER_U {
+    LowPart: u32,
+    HighPart: u32,
+}
+
+#[derive(Clone, Copy)]
+#[repr(C)]
+union LARGE_INTEGER {
+  __unnamed__: LARGE_INTEGER_U,
+  u: LARGE_INTEGER_U,
+  QuadPart: u64,
+}
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern "C" {
+    fn increment_all_parts(_: LARGE_INTEGER) -> LARGE_INTEGER;
+}
+
+fn main() {
+    unsafe {
+        let mut li = LARGE_INTEGER { QuadPart: 0 };
+        let li_c = increment_all_parts(li);
+        li.__unnamed__.LowPart += 1;
+        li.__unnamed__.HighPart += 1;
+        li.u.LowPart += 1;
+        li.u.HighPart += 1;
+        li.QuadPart += 1;
+        assert_eq!(li.QuadPart, li_c.QuadPart);
+    }
+}
diff --git a/src/test/run-pass/abi/variadic-ffi.rs b/src/test/run-pass/abi/variadic-ffi.rs
new file mode 100644
index 0000000000000..d6fbb1773b29f
--- /dev/null
+++ b/src/test/run-pass/abi/variadic-ffi.rs
@@ -0,0 +1,83 @@
+// ignore-wasm32-bare no libc to test ffi with
+#![feature(c_variadic)]
+
+use std::ffi::VaList;
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern {
+    fn rust_interesting_average(_: u64, ...) -> f64;
+
+    // FIXME: we need to disable this lint for `VaList`,
+    // since it contains a `MaybeUninit<i32>` on the asmjs target,
+    // and this type isn't FFI-safe. This is OK for now,
+    // since the type is layout-compatible with `i32`.
+    #[cfg_attr(target_arch = "asmjs", allow(improper_ctypes))]
+    fn rust_valist_interesting_average(_: u64, _: VaList) -> f64;
+}
+
+pub unsafe extern "C" fn test_valist_forward(n: u64, mut ap: ...) -> f64 {
+    rust_valist_interesting_average(n, ap.as_va_list())
+}
+
+pub unsafe extern "C" fn test_va_copy(_: u64, mut ap: ...) {
+    let mut ap2 = ap.clone();
+    assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 30);
+
+    // Advance one pair in the copy before checking
+    let mut ap2 = ap.clone();
+    let _ = ap2.arg::<u64>();
+    let _ = ap2.arg::<f64>();
+    assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 50);
+
+    // Advance one pair in the original
+    let _ = ap.arg::<u64>();
+    let _ = ap.arg::<f64>();
+
+    let mut ap2 = ap.clone();
+    assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 50);
+
+    let mut ap2 = ap.clone();
+    let _ = ap2.arg::<u64>();
+    let _ = ap2.arg::<f64>();
+    assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 70);
+}
+
+pub fn main() {
+    // Call without variadic arguments
+    unsafe {
+        assert!(rust_interesting_average(0).is_nan());
+    }
+
+    // Call with direct arguments
+    unsafe {
+        assert_eq!(rust_interesting_average(1, 10i64, 10.0f64) as i64, 20);
+    }
+
+    // Call with named arguments, variable number of them
+    let (x1, x2, x3, x4) = (10i64, 10.0f64, 20i64, 20.0f64);
+    unsafe {
+        assert_eq!(rust_interesting_average(2, x1, x2, x3, x4) as i64, 30);
+    }
+
+    // A function that takes a function pointer
+    unsafe fn call(fp: unsafe extern fn(u64, ...) -> f64) {
+        let (x1, x2, x3, x4) = (10i64, 10.0f64, 20i64, 20.0f64);
+        assert_eq!(fp(2, x1, x2, x3, x4) as i64, 30);
+    }
+
+    unsafe {
+        call(rust_interesting_average);
+
+        // Make a function pointer, pass indirectly
+        let x: unsafe extern fn(u64, ...) -> f64 = rust_interesting_average;
+        call(x);
+    }
+
+    unsafe {
+        assert_eq!(test_valist_forward(2, 10i64, 10f64, 20i64, 20f64) as i64, 30);
+    }
+
+    unsafe {
+        test_va_copy(4, 10i64, 10f64, 20i64, 20f64, 30i64, 30f64, 40i64, 40f64);
+    }
+}

From 98325eb592f537e87100199c0c67682306df3fa4 Mon Sep 17 00:00:00 2001
From: Kevin Per <kevin.per@protonmail.com>
Date: Tue, 9 Jul 2019 09:05:45 +0200
Subject: [PATCH 11/35] Grouping ABI tests (2) #62401

---
 .../abi/extern/extern-pass-TwoU32s.rs         | 25 +++++++++++++++++++
 .../abi/extern/extern-pass-TwoU64s.rs         | 25 +++++++++++++++++++
 .../run-pass/abi/extern/extern-pass-u32.rs    | 16 ++++++++++++
 .../run-pass/abi/extern/extern-pass-u64.rs    | 16 ++++++++++++
 4 files changed, 82 insertions(+)
 create mode 100644 src/test/run-pass/abi/extern/extern-pass-TwoU32s.rs
 create mode 100644 src/test/run-pass/abi/extern/extern-pass-TwoU64s.rs
 create mode 100644 src/test/run-pass/abi/extern/extern-pass-u32.rs
 create mode 100644 src/test/run-pass/abi/extern/extern-pass-u64.rs

diff --git a/src/test/run-pass/abi/extern/extern-pass-TwoU32s.rs b/src/test/run-pass/abi/extern/extern-pass-TwoU32s.rs
new file mode 100644
index 0000000000000..fb18aa8d22fda
--- /dev/null
+++ b/src/test/run-pass/abi/extern/extern-pass-TwoU32s.rs
@@ -0,0 +1,25 @@
+// run-pass
+#![allow(improper_ctypes)]
+
+// ignore-wasm32-bare no libc for ffi testing
+
+// Test a foreign function that accepts and returns a struct
+// by value.
+
+#[derive(Copy, Clone, PartialEq, Debug)]
+pub struct TwoU32s {
+    one: u32, two: u32
+}
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern {
+    pub fn rust_dbg_extern_identity_TwoU32s(v: TwoU32s) -> TwoU32s;
+}
+
+pub fn main() {
+    unsafe {
+        let x = TwoU32s {one: 22, two: 23};
+        let y = rust_dbg_extern_identity_TwoU32s(x);
+        assert_eq!(x, y);
+    }
+}
diff --git a/src/test/run-pass/abi/extern/extern-pass-TwoU64s.rs b/src/test/run-pass/abi/extern/extern-pass-TwoU64s.rs
new file mode 100644
index 0000000000000..419648263aa9b
--- /dev/null
+++ b/src/test/run-pass/abi/extern/extern-pass-TwoU64s.rs
@@ -0,0 +1,25 @@
+// run-pass
+#![allow(improper_ctypes)]
+
+// ignore-wasm32-bare no libc for ffi testing
+
+// Test a foreign function that accepts and returns a struct
+// by value.
+
+#[derive(Copy, Clone, PartialEq, Debug)]
+pub struct TwoU64s {
+    one: u64, two: u64
+}
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern {
+    pub fn rust_dbg_extern_identity_TwoU64s(v: TwoU64s) -> TwoU64s;
+}
+
+pub fn main() {
+    unsafe {
+        let x = TwoU64s {one: 22, two: 23};
+        let y = rust_dbg_extern_identity_TwoU64s(x);
+        assert_eq!(x, y);
+    }
+}
diff --git a/src/test/run-pass/abi/extern/extern-pass-u32.rs b/src/test/run-pass/abi/extern/extern-pass-u32.rs
new file mode 100644
index 0000000000000..f2efdb7d3664e
--- /dev/null
+++ b/src/test/run-pass/abi/extern/extern-pass-u32.rs
@@ -0,0 +1,16 @@
+// run-pass
+// ignore-wasm32-bare no libc for ffi testing
+
+// Test a function that takes/returns a u32.
+
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern {
+    pub fn rust_dbg_extern_identity_u32(v: u32) -> u32;
+}
+
+pub fn main() {
+    unsafe {
+        assert_eq!(22, rust_dbg_extern_identity_u32(22));
+    }
+}
diff --git a/src/test/run-pass/abi/extern/extern-pass-u64.rs b/src/test/run-pass/abi/extern/extern-pass-u64.rs
new file mode 100644
index 0000000000000..975446d430c28
--- /dev/null
+++ b/src/test/run-pass/abi/extern/extern-pass-u64.rs
@@ -0,0 +1,16 @@
+// run-pass
+// ignore-wasm32-bare no libc for ffi testing
+
+// Test a call to a function that takes/returns a u64.
+
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern {
+    pub fn rust_dbg_extern_identity_u64(v: u64) -> u64;
+}
+
+pub fn main() {
+    unsafe {
+        assert_eq!(22, rust_dbg_extern_identity_u64(22));
+    }
+}

From cac53fe3f24f9862d7faa85296f348e17c729bc4 Mon Sep 17 00:00:00 2001
From: Kevin Per <kevin.per@protonmail.com>
Date: Thu, 11 Jul 2019 19:40:09 +0200
Subject: [PATCH 12/35] Fixing broken tests #62401

The grouping led to a lot of `mv`. Therefore, some relative paths were
wrong. In this commit the dependent files were also moved so that the paths
work again.
---
 .../anon-extern-mod-cross-crate-2.rs          | 14 ++++++++++
 .../run-pass/abi/duplicated-external-mods.rs  |  8 ++++++
 .../run-pass/abi/extern/extern-crosscrate.rs  | 21 +++++++++++++++
 src/test/run-pass/abi/foreign/foreign-dupe.rs | 17 ++++++++++++
 .../run-pass/abi/invoke-external-foreign.rs   | 16 ++++++++++++
 .../abi/issues/auxiliary/issue-25185-2.rs     |  3 +++
 src/test/run-pass/abi/issues/issue-25185.rs   | 13 ++++++++++
 .../abi/proc_macro/auxiliary/test-macros.rs   | 26 +++++++++++++++++++
 src/test/run-pass/abi/stack-probes-lto.rs     | 18 +++++++++++++
 9 files changed, 136 insertions(+)
 create mode 100644 src/test/run-pass/abi/cross-crate/anon-extern-mod-cross-crate-2.rs
 create mode 100644 src/test/run-pass/abi/duplicated-external-mods.rs
 create mode 100644 src/test/run-pass/abi/extern/extern-crosscrate.rs
 create mode 100644 src/test/run-pass/abi/foreign/foreign-dupe.rs
 create mode 100644 src/test/run-pass/abi/invoke-external-foreign.rs
 create mode 100644 src/test/run-pass/abi/issues/auxiliary/issue-25185-2.rs
 create mode 100644 src/test/run-pass/abi/issues/issue-25185.rs
 create mode 100644 src/test/run-pass/abi/proc_macro/auxiliary/test-macros.rs
 create mode 100644 src/test/run-pass/abi/stack-probes-lto.rs

diff --git a/src/test/run-pass/abi/cross-crate/anon-extern-mod-cross-crate-2.rs b/src/test/run-pass/abi/cross-crate/anon-extern-mod-cross-crate-2.rs
new file mode 100644
index 0000000000000..77168be5374b2
--- /dev/null
+++ b/src/test/run-pass/abi/cross-crate/anon-extern-mod-cross-crate-2.rs
@@ -0,0 +1,14 @@
+// run-pass
+// aux-build:anon-extern-mod-cross-crate-1.rs
+// pretty-expanded FIXME #23616
+// ignore-wasm32-bare no libc to test ffi with
+
+extern crate anonexternmod;
+
+use anonexternmod::rust_get_test_int;
+
+pub fn main() {
+    unsafe {
+        rust_get_test_int();
+    }
+}
diff --git a/src/test/run-pass/abi/duplicated-external-mods.rs b/src/test/run-pass/abi/duplicated-external-mods.rs
new file mode 100644
index 0000000000000..f2c1e1f654016
--- /dev/null
+++ b/src/test/run-pass/abi/duplicated-external-mods.rs
@@ -0,0 +1,8 @@
+// aux-build:anon-extern-mod-cross-crate-1.rs
+// aux-build:anon-extern-mod-cross-crate-1.rs
+// pretty-expanded FIXME #23616
+// ignore-wasm32-bare no libc to test ffi with
+
+extern crate anonexternmod;
+
+pub fn main() { }
diff --git a/src/test/run-pass/abi/extern/extern-crosscrate.rs b/src/test/run-pass/abi/extern/extern-crosscrate.rs
new file mode 100644
index 0000000000000..123ce20ca262f
--- /dev/null
+++ b/src/test/run-pass/abi/extern/extern-crosscrate.rs
@@ -0,0 +1,21 @@
+// run-pass
+// aux-build:extern-crosscrate-source.rs
+// ignore-wasm32-bare no libc to test ffi with
+
+#![feature(rustc_private)]
+
+extern crate externcallback;
+extern crate libc;
+
+fn fact(n: libc::uintptr_t) -> libc::uintptr_t {
+    unsafe {
+        println!("n = {}", n);
+        externcallback::rustrt::rust_dbg_call(externcallback::cb, n)
+    }
+}
+
+pub fn main() {
+    let result = fact(10);
+    println!("result = {}", result);
+    assert_eq!(result, 3628800);
+}
diff --git a/src/test/run-pass/abi/foreign/foreign-dupe.rs b/src/test/run-pass/abi/foreign/foreign-dupe.rs
new file mode 100644
index 0000000000000..3c9f0f583d487
--- /dev/null
+++ b/src/test/run-pass/abi/foreign/foreign-dupe.rs
@@ -0,0 +1,17 @@
+// run-pass
+// aux-build:foreign_lib.rs
+// ignore-wasm32-bare no libc to test ffi with
+
+// Check that we can still call duplicated extern (imported) functions
+// which were declared in another crate. See issues #32740 and #32783.
+
+
+extern crate foreign_lib;
+
+pub fn main() {
+    unsafe {
+        let x = foreign_lib::rustrt::rust_get_test_int();
+        assert_eq!(x, foreign_lib::rustrt2::rust_get_test_int());
+        assert_eq!(x as *const _, foreign_lib::rustrt3::rust_get_test_int());
+    }
+}
diff --git a/src/test/run-pass/abi/invoke-external-foreign.rs b/src/test/run-pass/abi/invoke-external-foreign.rs
new file mode 100644
index 0000000000000..d34933cde4246
--- /dev/null
+++ b/src/test/run-pass/abi/invoke-external-foreign.rs
@@ -0,0 +1,16 @@
+// aux-build:foreign_lib.rs
+// ignore-wasm32-bare no libc to test ffi with
+
+// The purpose of this test is to check that we can
+// successfully (and safely) invoke external, cdecl
+// functions from outside the crate.
+
+// pretty-expanded FIXME #23616
+
+extern crate foreign_lib;
+
+pub fn main() {
+    unsafe {
+        let _foo = foreign_lib::rustrt::rust_get_test_int();
+    }
+}
diff --git a/src/test/run-pass/abi/issues/auxiliary/issue-25185-2.rs b/src/test/run-pass/abi/issues/auxiliary/issue-25185-2.rs
new file mode 100644
index 0000000000000..7ce3df255a331
--- /dev/null
+++ b/src/test/run-pass/abi/issues/auxiliary/issue-25185-2.rs
@@ -0,0 +1,3 @@
+extern crate issue_25185_1;
+
+pub use issue_25185_1::rust_dbg_extern_identity_u32;
diff --git a/src/test/run-pass/abi/issues/issue-25185.rs b/src/test/run-pass/abi/issues/issue-25185.rs
new file mode 100644
index 0000000000000..383c9a1e9c4ab
--- /dev/null
+++ b/src/test/run-pass/abi/issues/issue-25185.rs
@@ -0,0 +1,13 @@
+// run-pass
+// aux-build:issue-25185-1.rs
+// aux-build:issue-25185-2.rs
+// ignore-wasm32-bare no libc for ffi testing
+
+extern crate issue_25185_2;
+
+fn main() {
+    let x = unsafe {
+        issue_25185_2::rust_dbg_extern_identity_u32(1)
+    };
+    assert_eq!(x, 1);
+}
diff --git a/src/test/run-pass/abi/proc_macro/auxiliary/test-macros.rs b/src/test/run-pass/abi/proc_macro/auxiliary/test-macros.rs
new file mode 100644
index 0000000000000..15fe3804f9b4f
--- /dev/null
+++ b/src/test/run-pass/abi/proc_macro/auxiliary/test-macros.rs
@@ -0,0 +1,26 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+
+#[proc_macro_attribute]
+pub fn nop_attr(_attr: TokenStream, input: TokenStream) -> TokenStream {
+    assert!(_attr.to_string().is_empty());
+    input
+}
+
+#[proc_macro_attribute]
+pub fn no_output(_attr: TokenStream, _input: TokenStream) -> TokenStream {
+    assert!(_attr.to_string().is_empty());
+    assert!(!_input.to_string().is_empty());
+    "".parse().unwrap()
+}
+
+#[proc_macro]
+pub fn emit_input(input: TokenStream) -> TokenStream {
+    input
+}
diff --git a/src/test/run-pass/abi/stack-probes-lto.rs b/src/test/run-pass/abi/stack-probes-lto.rs
new file mode 100644
index 0000000000000..1274f032a3e29
--- /dev/null
+++ b/src/test/run-pass/abi/stack-probes-lto.rs
@@ -0,0 +1,18 @@
+// ignore-arm
+// ignore-aarch64
+// ignore-mips
+// ignore-mips64
+// ignore-powerpc
+// ignore-s390x
+// ignore-sparc
+// ignore-sparc64
+// ignore-wasm
+// ignore-cloudabi no processes
+// ignore-emscripten no processes
+// ignore-sgx no processes
+// ignore-musl FIXME #31506
+// ignore-pretty
+// compile-flags: -C lto
+// no-prefer-dynamic
+
+include!("stack-probes.rs");

From 5941acd80faaf9043cb48737c47d0b94023eddc3 Mon Sep 17 00:00:00 2001
From: Marco A L Barbosa <malbarbo@gmail.com>
Date: Tue, 30 Jul 2019 16:31:26 -0300
Subject: [PATCH 13/35] Use libunwind from llvm-project submodule for musl
 targets

---
 src/bootstrap/sanity.rs                 |  4 ----
 src/ci/docker/scripts/musl-toolchain.sh | 26 -------------------------
 src/ci/docker/scripts/musl.sh           | 26 ++-----------------------
 src/libunwind/Cargo.toml                |  4 ++--
 src/libunwind/build.rs                  | 16 +++++++++++----
 5 files changed, 16 insertions(+), 60 deletions(-)

diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs
index 4e3930c8da7fc..bffe748f37cc1 100644
--- a/src/bootstrap/sanity.rs
+++ b/src/bootstrap/sanity.rs
@@ -202,10 +202,6 @@ pub fn check(build: &mut Build) {
                         panic!("couldn't find libc.a in musl dir: {}",
                                root.join("lib").display());
                     }
-                    if fs::metadata(root.join("lib/libunwind.a")).is_err() {
-                        panic!("couldn't find libunwind.a in musl dir: {}",
-                               root.join("lib").display());
-                    }
                 }
                 None => {
                     panic!("when targeting MUSL either the rust.musl-root \
diff --git a/src/ci/docker/scripts/musl-toolchain.sh b/src/ci/docker/scripts/musl-toolchain.sh
index 55899fa6c3e69..74ba2f0eadb25 100644
--- a/src/ci/docker/scripts/musl-toolchain.sh
+++ b/src/ci/docker/scripts/musl-toolchain.sh
@@ -54,29 +54,3 @@ if [ "$REPLACE_CC" = "1" ]; then
         ln -s $TARGET-g++ /usr/local/bin/$exec
     done
 fi
-
-export CC=$TARGET-gcc
-export CXX=$TARGET-g++
-
-LLVM=70
-
-# may have been downloaded in a previous run
-if [ ! -d libunwind-release_$LLVM ]; then
-  curl -L https://github.com/llvm-mirror/llvm/archive/release_$LLVM.tar.gz | tar xzf -
-  curl -L https://github.com/llvm-mirror/libunwind/archive/release_$LLVM.tar.gz | tar xzf -
-fi
-
-# fixme(mati865): Replace it with https://github.com/rust-lang/rust/pull/59089
-mkdir libunwind-build
-cd libunwind-build
-cmake ../libunwind-release_$LLVM \
-          -DLLVM_PATH=/build/llvm-release_$LLVM \
-          -DLIBUNWIND_ENABLE_SHARED=0 \
-          -DCMAKE_C_COMPILER=$CC \
-          -DCMAKE_CXX_COMPILER=$CXX \
-          -DCMAKE_C_FLAGS="$CFLAGS" \
-          -DCMAKE_CXX_FLAGS="$CXXFLAGS"
-
-hide_output make -j$(nproc)
-cp lib/libunwind.a $OUTPUT/$TARGET/lib
-cd - && rm -rf libunwind-build
diff --git a/src/ci/docker/scripts/musl.sh b/src/ci/docker/scripts/musl.sh
index c2cf77d56cb3b..d847c407aba67 100644
--- a/src/ci/docker/scripts/musl.sh
+++ b/src/ci/docker/scripts/musl.sh
@@ -20,6 +20,8 @@ exit 1
 TAG=$1
 shift
 
+# Ancient binutils versions don't understand debug symbols produced by more recent tools.
+# Apparently applying `-fPIC` everywhere allows them to link successfully.
 export CFLAGS="-fPIC $CFLAGS"
 
 MUSL=musl-1.1.22
@@ -38,27 +40,3 @@ else
 fi
 hide_output make install
 hide_output make clean
-
-cd ..
-
-LLVM=70
-
-# may have been downloaded in a previous run
-if [ ! -d libunwind-release_$LLVM ]; then
-  curl -L https://github.com/llvm-mirror/llvm/archive/release_$LLVM.tar.gz | tar xzf -
-  curl -L https://github.com/llvm-mirror/libunwind/archive/release_$LLVM.tar.gz | tar xzf -
-fi
-
-mkdir libunwind-build
-cd libunwind-build
-cmake ../libunwind-release_$LLVM \
-          -DLLVM_PATH=/build/llvm-release_$LLVM \
-          -DLIBUNWIND_ENABLE_SHARED=0 \
-          -DCMAKE_C_COMPILER=$CC \
-          -DCMAKE_CXX_COMPILER=$CXX \
-          -DCMAKE_C_FLAGS="$CFLAGS" \
-          -DCMAKE_CXX_FLAGS="$CXXFLAGS"
-
-hide_output make -j$(nproc)
-cp lib/libunwind.a /musl-$TAG/lib
-cd ../ && rm -rf libunwind-build
diff --git a/src/libunwind/Cargo.toml b/src/libunwind/Cargo.toml
index f0f1bab425d7a..f10df8c85ba0a 100644
--- a/src/libunwind/Cargo.toml
+++ b/src/libunwind/Cargo.toml
@@ -22,7 +22,7 @@ compiler_builtins = "0.1.0"
 cfg-if = "0.1.8"
 
 [build-dependencies]
-cc = { optional = true, version = "1.0.1" }
+cc = { version = "1.0.1" }
 
 [features]
-llvm-libunwind = ["cc"]
+llvm-libunwind = []
diff --git a/src/libunwind/build.rs b/src/libunwind/build.rs
index c1b0dbc0881d3..a266407c60294 100644
--- a/src/libunwind/build.rs
+++ b/src/libunwind/build.rs
@@ -5,14 +5,14 @@ fn main() {
     let target = env::var("TARGET").expect("TARGET was not set");
 
     if cfg!(feature = "llvm-libunwind") &&
-        (target.contains("linux") ||
+        ((target.contains("linux") && !target.contains("musl")) ||
          target.contains("fuchsia")) {
         // Build the unwinding from libunwind C/C++ source code.
-        #[cfg(feature = "llvm-libunwind")]
         llvm_libunwind::compile();
     } else if target.contains("linux") {
         if target.contains("musl") {
-            // musl is handled in lib.rs
+            // linking for musl is handled in lib.rs
+            llvm_libunwind::compile();
         } else if !target.contains("android") {
             println!("cargo:rustc-link-lib=gcc_s");
         }
@@ -44,7 +44,6 @@ fn main() {
     }
 }
 
-#[cfg(feature = "llvm-libunwind")]
 mod llvm_libunwind {
     use std::env;
     use std::path::Path;
@@ -96,6 +95,15 @@ mod llvm_libunwind {
             cfg.file(root.join("src").join(src));
         }
 
+        if target_env == "musl" {
+            // use the same C compiler command to compile C++ code so we do not need to setup the
+            // C++ compiler env variables on the builders
+            cfg.cpp(false);
+            // linking for musl is handled in lib.rs
+            cfg.cargo_metadata(false);
+            println!("cargo:rustc-link-search=native={}", env::var("OUT_DIR").unwrap());
+        }
+
         cfg.compile("unwind");
     }
 }

From df713dd39709bfdc34f364cd78d345a29d7b9d8a Mon Sep 17 00:00:00 2001
From: Kevin Per <kevin.per@protonmail.com>
Date: Thu, 15 Aug 2019 16:00:54 +0200
Subject: [PATCH 14/35] Group all ui tests and move to abi #62593

---
 src/test/ui/{ => abi}/abi-sysv64-arg-passing.rs                   | 0
 src/test/ui/{ => abi}/abi-sysv64-register-usage.rs                | 0
 src/test/ui/{ => abi}/abort-on-c-abi.rs                           | 0
 src/test/ui/{ => abi}/anon-extern-mod.rs                          | 0
 src/test/ui/{ => abi}/auxiliary/anon-extern-mod-cross-crate-1.rs  | 0
 src/test/ui/{ => abi}/auxiliary/foreign_lib.rs                    | 0
 src/test/ui/{ => abi}/c-stack-as-value.rs                         | 0
 src/test/ui/{ => abi}/cabi-int-widening.rs                        | 0
 .../{ => abi}/consts/auxiliary/anon-extern-mod-cross-crate-1.rs   | 0
 .../ui/{ => abi}/cross-crate/anon-extern-mod-cross-crate-2.rs     | 0
 .../cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs        | 0
 src/test/ui/{ => abi}/duplicated-external-mods.rs                 | 0
 .../ui/{ => abi}/extern/auxiliary/extern-crosscrate-source.rs     | 0
 src/test/ui/{ => abi}/extern/extern-call-deep.rs                  | 0
 src/test/ui/{ => abi}/extern/extern-call-deep2.rs                 | 0
 src/test/ui/{ => abi}/extern/extern-call-direct.rs                | 0
 src/test/ui/{ => abi}/extern/extern-call-indirect.rs              | 0
 src/test/ui/{ => abi}/extern/extern-call-scrub.rs                 | 0
 src/test/ui/{ => abi}/extern/extern-crosscrate.rs                 | 0
 src/test/ui/{ => abi}/extern/extern-pass-TwoU16s.rs               | 0
 src/test/ui/{ => abi}/extern/extern-pass-TwoU32s.rs               | 0
 src/test/ui/{ => abi}/extern/extern-pass-TwoU64s.rs               | 0
 src/test/ui/{ => abi}/extern/extern-pass-TwoU8s.rs                | 0
 src/test/ui/{ => abi}/extern/extern-pass-char.rs                  | 0
 src/test/ui/{ => abi}/extern/extern-pass-double.rs                | 0
 src/test/ui/{ => abi}/extern/extern-pass-empty.rs                 | 0
 src/test/ui/{ => abi}/extern/extern-pass-u32.rs                   | 0
 src/test/ui/{ => abi}/extern/extern-pass-u64.rs                   | 0
 src/test/ui/{ => abi}/extern/extern-return-TwoU16s.rs             | 0
 src/test/ui/{ => abi}/extern/extern-return-TwoU32s.rs             | 0
 src/test/ui/{ => abi}/extern/extern-return-TwoU64s.rs             | 0
 src/test/ui/{ => abi}/extern/extern-return-TwoU8s.rs              | 0
 src/test/ui/{ => abi}/foreign/auxiliary/foreign_lib.rs            | 0
 src/test/ui/{ => abi}/foreign/foreign-call-no-runtime.rs          | 0
 src/test/ui/{ => abi}/foreign/foreign-dupe.rs                     | 0
 src/test/ui/{ => abi}/foreign/foreign-fn-with-byval.rs            | 0
 src/test/ui/{ => abi}/foreign/foreign-no-abi.rs                   | 0
 src/test/ui/{ => abi}/invoke-external-foreign.rs                  | 0
 src/test/ui/{ => abi}/lib-defaults.rs                             | 0
 src/test/ui/{ => abi}/macros/macros-in-extern.rs                  | 0
 src/test/ui/{ => abi}/macros/macros-in-extern.stderr              | 0
 src/test/ui/{ => abi}/mir/mir_codegen_calls_variadic.rs           | 0
 src/test/ui/{ => abi}/numbers-arithmetic/i128-ffi.rs              | 0
 src/test/ui/{ => abi}/proc-macro/auxiliary/test-macros.rs         | 0
 src/test/ui/{ => abi}/proc-macro/macros-in-extern.rs              | 0
 src/test/ui/{ => abi}/proc-macro/macros-in-extern.stderr          | 0
 src/test/ui/{ => abi}/segfault-no-out-of-stack.rs                 | 0
 src/test/ui/{ => abi}/stack-probes-lto.rs                         | 0
 src/test/ui/{ => abi}/stack-probes.rs                             | 0
 src/test/ui/{ => abi}/statics/static-mut-foreign.rs               | 0
 src/test/ui/{structs-enums => abi/struct-enums}/struct-return.rs  | 0
 src/test/ui/{ => abi}/union/union-c-interop.rs                    | 0
 src/test/ui/{ => abi}/variadic-ffi.rs                             | 0
 53 files changed, 0 insertions(+), 0 deletions(-)
 rename src/test/ui/{ => abi}/abi-sysv64-arg-passing.rs (100%)
 rename src/test/ui/{ => abi}/abi-sysv64-register-usage.rs (100%)
 rename src/test/ui/{ => abi}/abort-on-c-abi.rs (100%)
 rename src/test/ui/{ => abi}/anon-extern-mod.rs (100%)
 rename src/test/ui/{ => abi}/auxiliary/anon-extern-mod-cross-crate-1.rs (100%)
 rename src/test/ui/{ => abi}/auxiliary/foreign_lib.rs (100%)
 rename src/test/ui/{ => abi}/c-stack-as-value.rs (100%)
 rename src/test/ui/{ => abi}/cabi-int-widening.rs (100%)
 rename src/test/ui/{ => abi}/consts/auxiliary/anon-extern-mod-cross-crate-1.rs (100%)
 rename src/test/ui/{ => abi}/cross-crate/anon-extern-mod-cross-crate-2.rs (100%)
 rename src/test/ui/{ => abi}/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs (100%)
 rename src/test/ui/{ => abi}/duplicated-external-mods.rs (100%)
 rename src/test/ui/{ => abi}/extern/auxiliary/extern-crosscrate-source.rs (100%)
 rename src/test/ui/{ => abi}/extern/extern-call-deep.rs (100%)
 rename src/test/ui/{ => abi}/extern/extern-call-deep2.rs (100%)
 rename src/test/ui/{ => abi}/extern/extern-call-direct.rs (100%)
 rename src/test/ui/{ => abi}/extern/extern-call-indirect.rs (100%)
 rename src/test/ui/{ => abi}/extern/extern-call-scrub.rs (100%)
 rename src/test/ui/{ => abi}/extern/extern-crosscrate.rs (100%)
 rename src/test/ui/{ => abi}/extern/extern-pass-TwoU16s.rs (100%)
 rename src/test/ui/{ => abi}/extern/extern-pass-TwoU32s.rs (100%)
 rename src/test/ui/{ => abi}/extern/extern-pass-TwoU64s.rs (100%)
 rename src/test/ui/{ => abi}/extern/extern-pass-TwoU8s.rs (100%)
 rename src/test/ui/{ => abi}/extern/extern-pass-char.rs (100%)
 rename src/test/ui/{ => abi}/extern/extern-pass-double.rs (100%)
 rename src/test/ui/{ => abi}/extern/extern-pass-empty.rs (100%)
 rename src/test/ui/{ => abi}/extern/extern-pass-u32.rs (100%)
 rename src/test/ui/{ => abi}/extern/extern-pass-u64.rs (100%)
 rename src/test/ui/{ => abi}/extern/extern-return-TwoU16s.rs (100%)
 rename src/test/ui/{ => abi}/extern/extern-return-TwoU32s.rs (100%)
 rename src/test/ui/{ => abi}/extern/extern-return-TwoU64s.rs (100%)
 rename src/test/ui/{ => abi}/extern/extern-return-TwoU8s.rs (100%)
 rename src/test/ui/{ => abi}/foreign/auxiliary/foreign_lib.rs (100%)
 rename src/test/ui/{ => abi}/foreign/foreign-call-no-runtime.rs (100%)
 rename src/test/ui/{ => abi}/foreign/foreign-dupe.rs (100%)
 rename src/test/ui/{ => abi}/foreign/foreign-fn-with-byval.rs (100%)
 rename src/test/ui/{ => abi}/foreign/foreign-no-abi.rs (100%)
 rename src/test/ui/{ => abi}/invoke-external-foreign.rs (100%)
 rename src/test/ui/{ => abi}/lib-defaults.rs (100%)
 rename src/test/ui/{ => abi}/macros/macros-in-extern.rs (100%)
 rename src/test/ui/{ => abi}/macros/macros-in-extern.stderr (100%)
 rename src/test/ui/{ => abi}/mir/mir_codegen_calls_variadic.rs (100%)
 rename src/test/ui/{ => abi}/numbers-arithmetic/i128-ffi.rs (100%)
 rename src/test/ui/{ => abi}/proc-macro/auxiliary/test-macros.rs (100%)
 rename src/test/ui/{ => abi}/proc-macro/macros-in-extern.rs (100%)
 rename src/test/ui/{ => abi}/proc-macro/macros-in-extern.stderr (100%)
 rename src/test/ui/{ => abi}/segfault-no-out-of-stack.rs (100%)
 rename src/test/ui/{ => abi}/stack-probes-lto.rs (100%)
 rename src/test/ui/{ => abi}/stack-probes.rs (100%)
 rename src/test/ui/{ => abi}/statics/static-mut-foreign.rs (100%)
 rename src/test/ui/{structs-enums => abi/struct-enums}/struct-return.rs (100%)
 rename src/test/ui/{ => abi}/union/union-c-interop.rs (100%)
 rename src/test/ui/{ => abi}/variadic-ffi.rs (100%)

diff --git a/src/test/ui/abi-sysv64-arg-passing.rs b/src/test/ui/abi/abi-sysv64-arg-passing.rs
similarity index 100%
rename from src/test/ui/abi-sysv64-arg-passing.rs
rename to src/test/ui/abi/abi-sysv64-arg-passing.rs
diff --git a/src/test/ui/abi-sysv64-register-usage.rs b/src/test/ui/abi/abi-sysv64-register-usage.rs
similarity index 100%
rename from src/test/ui/abi-sysv64-register-usage.rs
rename to src/test/ui/abi/abi-sysv64-register-usage.rs
diff --git a/src/test/ui/abort-on-c-abi.rs b/src/test/ui/abi/abort-on-c-abi.rs
similarity index 100%
rename from src/test/ui/abort-on-c-abi.rs
rename to src/test/ui/abi/abort-on-c-abi.rs
diff --git a/src/test/ui/anon-extern-mod.rs b/src/test/ui/abi/anon-extern-mod.rs
similarity index 100%
rename from src/test/ui/anon-extern-mod.rs
rename to src/test/ui/abi/anon-extern-mod.rs
diff --git a/src/test/ui/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/ui/abi/auxiliary/anon-extern-mod-cross-crate-1.rs
similarity index 100%
rename from src/test/ui/auxiliary/anon-extern-mod-cross-crate-1.rs
rename to src/test/ui/abi/auxiliary/anon-extern-mod-cross-crate-1.rs
diff --git a/src/test/ui/auxiliary/foreign_lib.rs b/src/test/ui/abi/auxiliary/foreign_lib.rs
similarity index 100%
rename from src/test/ui/auxiliary/foreign_lib.rs
rename to src/test/ui/abi/auxiliary/foreign_lib.rs
diff --git a/src/test/ui/c-stack-as-value.rs b/src/test/ui/abi/c-stack-as-value.rs
similarity index 100%
rename from src/test/ui/c-stack-as-value.rs
rename to src/test/ui/abi/c-stack-as-value.rs
diff --git a/src/test/ui/cabi-int-widening.rs b/src/test/ui/abi/cabi-int-widening.rs
similarity index 100%
rename from src/test/ui/cabi-int-widening.rs
rename to src/test/ui/abi/cabi-int-widening.rs
diff --git a/src/test/ui/consts/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/ui/abi/consts/auxiliary/anon-extern-mod-cross-crate-1.rs
similarity index 100%
rename from src/test/ui/consts/auxiliary/anon-extern-mod-cross-crate-1.rs
rename to src/test/ui/abi/consts/auxiliary/anon-extern-mod-cross-crate-1.rs
diff --git a/src/test/ui/cross-crate/anon-extern-mod-cross-crate-2.rs b/src/test/ui/abi/cross-crate/anon-extern-mod-cross-crate-2.rs
similarity index 100%
rename from src/test/ui/cross-crate/anon-extern-mod-cross-crate-2.rs
rename to src/test/ui/abi/cross-crate/anon-extern-mod-cross-crate-2.rs
diff --git a/src/test/ui/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/ui/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs
similarity index 100%
rename from src/test/ui/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs
rename to src/test/ui/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs
diff --git a/src/test/ui/duplicated-external-mods.rs b/src/test/ui/abi/duplicated-external-mods.rs
similarity index 100%
rename from src/test/ui/duplicated-external-mods.rs
rename to src/test/ui/abi/duplicated-external-mods.rs
diff --git a/src/test/ui/extern/auxiliary/extern-crosscrate-source.rs b/src/test/ui/abi/extern/auxiliary/extern-crosscrate-source.rs
similarity index 100%
rename from src/test/ui/extern/auxiliary/extern-crosscrate-source.rs
rename to src/test/ui/abi/extern/auxiliary/extern-crosscrate-source.rs
diff --git a/src/test/ui/extern/extern-call-deep.rs b/src/test/ui/abi/extern/extern-call-deep.rs
similarity index 100%
rename from src/test/ui/extern/extern-call-deep.rs
rename to src/test/ui/abi/extern/extern-call-deep.rs
diff --git a/src/test/ui/extern/extern-call-deep2.rs b/src/test/ui/abi/extern/extern-call-deep2.rs
similarity index 100%
rename from src/test/ui/extern/extern-call-deep2.rs
rename to src/test/ui/abi/extern/extern-call-deep2.rs
diff --git a/src/test/ui/extern/extern-call-direct.rs b/src/test/ui/abi/extern/extern-call-direct.rs
similarity index 100%
rename from src/test/ui/extern/extern-call-direct.rs
rename to src/test/ui/abi/extern/extern-call-direct.rs
diff --git a/src/test/ui/extern/extern-call-indirect.rs b/src/test/ui/abi/extern/extern-call-indirect.rs
similarity index 100%
rename from src/test/ui/extern/extern-call-indirect.rs
rename to src/test/ui/abi/extern/extern-call-indirect.rs
diff --git a/src/test/ui/extern/extern-call-scrub.rs b/src/test/ui/abi/extern/extern-call-scrub.rs
similarity index 100%
rename from src/test/ui/extern/extern-call-scrub.rs
rename to src/test/ui/abi/extern/extern-call-scrub.rs
diff --git a/src/test/ui/extern/extern-crosscrate.rs b/src/test/ui/abi/extern/extern-crosscrate.rs
similarity index 100%
rename from src/test/ui/extern/extern-crosscrate.rs
rename to src/test/ui/abi/extern/extern-crosscrate.rs
diff --git a/src/test/ui/extern/extern-pass-TwoU16s.rs b/src/test/ui/abi/extern/extern-pass-TwoU16s.rs
similarity index 100%
rename from src/test/ui/extern/extern-pass-TwoU16s.rs
rename to src/test/ui/abi/extern/extern-pass-TwoU16s.rs
diff --git a/src/test/ui/extern/extern-pass-TwoU32s.rs b/src/test/ui/abi/extern/extern-pass-TwoU32s.rs
similarity index 100%
rename from src/test/ui/extern/extern-pass-TwoU32s.rs
rename to src/test/ui/abi/extern/extern-pass-TwoU32s.rs
diff --git a/src/test/ui/extern/extern-pass-TwoU64s.rs b/src/test/ui/abi/extern/extern-pass-TwoU64s.rs
similarity index 100%
rename from src/test/ui/extern/extern-pass-TwoU64s.rs
rename to src/test/ui/abi/extern/extern-pass-TwoU64s.rs
diff --git a/src/test/ui/extern/extern-pass-TwoU8s.rs b/src/test/ui/abi/extern/extern-pass-TwoU8s.rs
similarity index 100%
rename from src/test/ui/extern/extern-pass-TwoU8s.rs
rename to src/test/ui/abi/extern/extern-pass-TwoU8s.rs
diff --git a/src/test/ui/extern/extern-pass-char.rs b/src/test/ui/abi/extern/extern-pass-char.rs
similarity index 100%
rename from src/test/ui/extern/extern-pass-char.rs
rename to src/test/ui/abi/extern/extern-pass-char.rs
diff --git a/src/test/ui/extern/extern-pass-double.rs b/src/test/ui/abi/extern/extern-pass-double.rs
similarity index 100%
rename from src/test/ui/extern/extern-pass-double.rs
rename to src/test/ui/abi/extern/extern-pass-double.rs
diff --git a/src/test/ui/extern/extern-pass-empty.rs b/src/test/ui/abi/extern/extern-pass-empty.rs
similarity index 100%
rename from src/test/ui/extern/extern-pass-empty.rs
rename to src/test/ui/abi/extern/extern-pass-empty.rs
diff --git a/src/test/ui/extern/extern-pass-u32.rs b/src/test/ui/abi/extern/extern-pass-u32.rs
similarity index 100%
rename from src/test/ui/extern/extern-pass-u32.rs
rename to src/test/ui/abi/extern/extern-pass-u32.rs
diff --git a/src/test/ui/extern/extern-pass-u64.rs b/src/test/ui/abi/extern/extern-pass-u64.rs
similarity index 100%
rename from src/test/ui/extern/extern-pass-u64.rs
rename to src/test/ui/abi/extern/extern-pass-u64.rs
diff --git a/src/test/ui/extern/extern-return-TwoU16s.rs b/src/test/ui/abi/extern/extern-return-TwoU16s.rs
similarity index 100%
rename from src/test/ui/extern/extern-return-TwoU16s.rs
rename to src/test/ui/abi/extern/extern-return-TwoU16s.rs
diff --git a/src/test/ui/extern/extern-return-TwoU32s.rs b/src/test/ui/abi/extern/extern-return-TwoU32s.rs
similarity index 100%
rename from src/test/ui/extern/extern-return-TwoU32s.rs
rename to src/test/ui/abi/extern/extern-return-TwoU32s.rs
diff --git a/src/test/ui/extern/extern-return-TwoU64s.rs b/src/test/ui/abi/extern/extern-return-TwoU64s.rs
similarity index 100%
rename from src/test/ui/extern/extern-return-TwoU64s.rs
rename to src/test/ui/abi/extern/extern-return-TwoU64s.rs
diff --git a/src/test/ui/extern/extern-return-TwoU8s.rs b/src/test/ui/abi/extern/extern-return-TwoU8s.rs
similarity index 100%
rename from src/test/ui/extern/extern-return-TwoU8s.rs
rename to src/test/ui/abi/extern/extern-return-TwoU8s.rs
diff --git a/src/test/ui/foreign/auxiliary/foreign_lib.rs b/src/test/ui/abi/foreign/auxiliary/foreign_lib.rs
similarity index 100%
rename from src/test/ui/foreign/auxiliary/foreign_lib.rs
rename to src/test/ui/abi/foreign/auxiliary/foreign_lib.rs
diff --git a/src/test/ui/foreign/foreign-call-no-runtime.rs b/src/test/ui/abi/foreign/foreign-call-no-runtime.rs
similarity index 100%
rename from src/test/ui/foreign/foreign-call-no-runtime.rs
rename to src/test/ui/abi/foreign/foreign-call-no-runtime.rs
diff --git a/src/test/ui/foreign/foreign-dupe.rs b/src/test/ui/abi/foreign/foreign-dupe.rs
similarity index 100%
rename from src/test/ui/foreign/foreign-dupe.rs
rename to src/test/ui/abi/foreign/foreign-dupe.rs
diff --git a/src/test/ui/foreign/foreign-fn-with-byval.rs b/src/test/ui/abi/foreign/foreign-fn-with-byval.rs
similarity index 100%
rename from src/test/ui/foreign/foreign-fn-with-byval.rs
rename to src/test/ui/abi/foreign/foreign-fn-with-byval.rs
diff --git a/src/test/ui/foreign/foreign-no-abi.rs b/src/test/ui/abi/foreign/foreign-no-abi.rs
similarity index 100%
rename from src/test/ui/foreign/foreign-no-abi.rs
rename to src/test/ui/abi/foreign/foreign-no-abi.rs
diff --git a/src/test/ui/invoke-external-foreign.rs b/src/test/ui/abi/invoke-external-foreign.rs
similarity index 100%
rename from src/test/ui/invoke-external-foreign.rs
rename to src/test/ui/abi/invoke-external-foreign.rs
diff --git a/src/test/ui/lib-defaults.rs b/src/test/ui/abi/lib-defaults.rs
similarity index 100%
rename from src/test/ui/lib-defaults.rs
rename to src/test/ui/abi/lib-defaults.rs
diff --git a/src/test/ui/macros/macros-in-extern.rs b/src/test/ui/abi/macros/macros-in-extern.rs
similarity index 100%
rename from src/test/ui/macros/macros-in-extern.rs
rename to src/test/ui/abi/macros/macros-in-extern.rs
diff --git a/src/test/ui/macros/macros-in-extern.stderr b/src/test/ui/abi/macros/macros-in-extern.stderr
similarity index 100%
rename from src/test/ui/macros/macros-in-extern.stderr
rename to src/test/ui/abi/macros/macros-in-extern.stderr
diff --git a/src/test/ui/mir/mir_codegen_calls_variadic.rs b/src/test/ui/abi/mir/mir_codegen_calls_variadic.rs
similarity index 100%
rename from src/test/ui/mir/mir_codegen_calls_variadic.rs
rename to src/test/ui/abi/mir/mir_codegen_calls_variadic.rs
diff --git a/src/test/ui/numbers-arithmetic/i128-ffi.rs b/src/test/ui/abi/numbers-arithmetic/i128-ffi.rs
similarity index 100%
rename from src/test/ui/numbers-arithmetic/i128-ffi.rs
rename to src/test/ui/abi/numbers-arithmetic/i128-ffi.rs
diff --git a/src/test/ui/proc-macro/auxiliary/test-macros.rs b/src/test/ui/abi/proc-macro/auxiliary/test-macros.rs
similarity index 100%
rename from src/test/ui/proc-macro/auxiliary/test-macros.rs
rename to src/test/ui/abi/proc-macro/auxiliary/test-macros.rs
diff --git a/src/test/ui/proc-macro/macros-in-extern.rs b/src/test/ui/abi/proc-macro/macros-in-extern.rs
similarity index 100%
rename from src/test/ui/proc-macro/macros-in-extern.rs
rename to src/test/ui/abi/proc-macro/macros-in-extern.rs
diff --git a/src/test/ui/proc-macro/macros-in-extern.stderr b/src/test/ui/abi/proc-macro/macros-in-extern.stderr
similarity index 100%
rename from src/test/ui/proc-macro/macros-in-extern.stderr
rename to src/test/ui/abi/proc-macro/macros-in-extern.stderr
diff --git a/src/test/ui/segfault-no-out-of-stack.rs b/src/test/ui/abi/segfault-no-out-of-stack.rs
similarity index 100%
rename from src/test/ui/segfault-no-out-of-stack.rs
rename to src/test/ui/abi/segfault-no-out-of-stack.rs
diff --git a/src/test/ui/stack-probes-lto.rs b/src/test/ui/abi/stack-probes-lto.rs
similarity index 100%
rename from src/test/ui/stack-probes-lto.rs
rename to src/test/ui/abi/stack-probes-lto.rs
diff --git a/src/test/ui/stack-probes.rs b/src/test/ui/abi/stack-probes.rs
similarity index 100%
rename from src/test/ui/stack-probes.rs
rename to src/test/ui/abi/stack-probes.rs
diff --git a/src/test/ui/statics/static-mut-foreign.rs b/src/test/ui/abi/statics/static-mut-foreign.rs
similarity index 100%
rename from src/test/ui/statics/static-mut-foreign.rs
rename to src/test/ui/abi/statics/static-mut-foreign.rs
diff --git a/src/test/ui/structs-enums/struct-return.rs b/src/test/ui/abi/struct-enums/struct-return.rs
similarity index 100%
rename from src/test/ui/structs-enums/struct-return.rs
rename to src/test/ui/abi/struct-enums/struct-return.rs
diff --git a/src/test/ui/union/union-c-interop.rs b/src/test/ui/abi/union/union-c-interop.rs
similarity index 100%
rename from src/test/ui/union/union-c-interop.rs
rename to src/test/ui/abi/union/union-c-interop.rs
diff --git a/src/test/ui/variadic-ffi.rs b/src/test/ui/abi/variadic-ffi.rs
similarity index 100%
rename from src/test/ui/variadic-ffi.rs
rename to src/test/ui/abi/variadic-ffi.rs

From a90d0876d17c8ce3cb903c867acd70cb8379de60 Mon Sep 17 00:00:00 2001
From: Kevin Per <kevin.per@protonmail.com>
Date: Thu, 15 Aug 2019 17:05:49 +0200
Subject: [PATCH 15/35] Move `test-macros.rs` back to `ui` to fix tests #62593

---
 src/test/ui/{abi => }/proc-macro/auxiliary/test-macros.rs | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename src/test/ui/{abi => }/proc-macro/auxiliary/test-macros.rs (100%)

diff --git a/src/test/ui/abi/proc-macro/auxiliary/test-macros.rs b/src/test/ui/proc-macro/auxiliary/test-macros.rs
similarity index 100%
rename from src/test/ui/abi/proc-macro/auxiliary/test-macros.rs
rename to src/test/ui/proc-macro/auxiliary/test-macros.rs

From 4a8ff5bb7c31c90a5be3e4d6a2e7e7211b4c8745 Mon Sep 17 00:00:00 2001
From: Kevin Per <kevin.per@protonmail.com>
Date: Thu, 15 Aug 2019 17:07:38 +0200
Subject: [PATCH 16/35] Remove `run-pass` directory #62593

---
 .../run-pass/abi/abi-sysv64-arg-passing.rs    | 366 ------------------
 .../run-pass/abi/abi-sysv64-register-usage.rs |  95 -----
 src/test/run-pass/abi/abort-on-c-abi.rs       |  36 --
 src/test/run-pass/abi/anon-extern-mod.rs      |  17 -
 .../anon-extern-mod-cross-crate-1.rs          |   9 -
 .../run-pass/abi/auxiliary/foreign_lib.rs     |  38 --
 src/test/run-pass/abi/c-stack-as-value.rs     |  17 -
 src/test/run-pass/abi/cabi-int-widening.rs    |  14 -
 .../anon-extern-mod-cross-crate-1.rs          |   9 -
 .../anon-extern-mod-cross-crate-2.rs          |  14 -
 .../anon-extern-mod-cross-crate-1.rs          |   9 -
 .../run-pass/abi/duplicated-external-mods.rs  |   8 -
 .../auxiliary/extern-crosscrate-source.rs     |  31 --
 .../run-pass/abi/extern/extern-call-deep.rs   |  39 --
 .../run-pass/abi/extern/extern-call-deep2.rs  |  44 ---
 .../abi/extern/extern-call-indirect.rs        |  38 --
 .../run-pass/abi/extern/extern-call-scrub.rs  |  48 ---
 .../run-pass/abi/extern/extern-crosscrate.rs  |  21 -
 .../abi/extern/extern-pass-TwoU16s.rs         |  25 --
 .../abi/extern/extern-pass-TwoU32s.rs         |  25 --
 .../abi/extern/extern-pass-TwoU64s.rs         |  25 --
 .../run-pass/abi/extern/extern-pass-TwoU8s.rs |  25 --
 .../run-pass/abi/extern/extern-pass-char.rs   |  16 -
 .../run-pass/abi/extern/extern-pass-double.rs |  13 -
 .../run-pass/abi/extern/extern-pass-empty.rs  |  55 ---
 .../run-pass/abi/extern/extern-pass-u32.rs    |  16 -
 .../run-pass/abi/extern/extern-pass-u64.rs    |  16 -
 .../abi/extern/extern-return-TwoU16s.rs       |  21 -
 .../abi/extern/extern-return-TwoU32s.rs       |  21 -
 .../abi/extern/extern-return-TwoU64s.rs       |  21 -
 .../abi/extern/extern-return-TwoU8s.rs        |  21 -
 .../abi/foreign/auxiliary/foreign_lib.rs      |  38 --
 .../abi/foreign/foreign-call-no-runtime.rs    |  55 ---
 src/test/run-pass/abi/foreign/foreign-dupe.rs |  17 -
 .../abi/foreign/foreign-fn-with-byval.rs      |  32 --
 .../run-pass/abi/foreign/foreign-no-abi.rs    |  22 --
 .../run-pass/abi/invoke-external-foreign.rs   |  16 -
 .../abi/issues/auxiliary/issue-25185-1.rs     |   8 -
 .../abi/issues/auxiliary/issue-25185-2.rs     |   3 -
 src/test/run-pass/abi/issues/issue-25185.rs   |  13 -
 src/test/run-pass/abi/issues/issue-28676.rs   |  35 --
 src/test/run-pass/abi/lib-defaults.rs         |  16 -
 .../run-pass/abi/macros/macros-in-extern.rs   |  30 --
 .../abi/mir/mir_codegen_calls_variadic.rs     |  22 --
 .../abi/numbers-arithmetic/i128-ffi.rs        |  31 --
 .../abi/proc_macro/auxiliary/test-macros.rs   |  26 --
 .../abi/proc_macro/macros-in-extern.rs        |  24 --
 .../abi/rfcs/rfc1717/library-override.rs      |  14 -
 .../run-pass/abi/segfault-no-out-of-stack.rs  |  48 ---
 src/test/run-pass/abi/stack-probes-lto.rs     |  18 -
 src/test/run-pass/abi/stack-probes.rs         |  67 ----
 .../abi/statics/static-mut-foreign.rs         |  41 --
 .../abi/structs-enums/struct-return.rs        |  64 ---
 .../run-pass/abi/union/union-c-interop.rs     |  37 --
 src/test/run-pass/abi/variadic-ffi.rs         |  83 ----
 55 files changed, 1913 deletions(-)
 delete mode 100644 src/test/run-pass/abi/abi-sysv64-arg-passing.rs
 delete mode 100644 src/test/run-pass/abi/abi-sysv64-register-usage.rs
 delete mode 100644 src/test/run-pass/abi/abort-on-c-abi.rs
 delete mode 100644 src/test/run-pass/abi/anon-extern-mod.rs
 delete mode 100644 src/test/run-pass/abi/auxiliary/anon-extern-mod-cross-crate-1.rs
 delete mode 100644 src/test/run-pass/abi/auxiliary/foreign_lib.rs
 delete mode 100644 src/test/run-pass/abi/c-stack-as-value.rs
 delete mode 100644 src/test/run-pass/abi/cabi-int-widening.rs
 delete mode 100644 src/test/run-pass/abi/consts/auxiliary/anon-extern-mod-cross-crate-1.rs
 delete mode 100644 src/test/run-pass/abi/cross-crate/anon-extern-mod-cross-crate-2.rs
 delete mode 100644 src/test/run-pass/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs
 delete mode 100644 src/test/run-pass/abi/duplicated-external-mods.rs
 delete mode 100644 src/test/run-pass/abi/extern/auxiliary/extern-crosscrate-source.rs
 delete mode 100644 src/test/run-pass/abi/extern/extern-call-deep.rs
 delete mode 100644 src/test/run-pass/abi/extern/extern-call-deep2.rs
 delete mode 100644 src/test/run-pass/abi/extern/extern-call-indirect.rs
 delete mode 100644 src/test/run-pass/abi/extern/extern-call-scrub.rs
 delete mode 100644 src/test/run-pass/abi/extern/extern-crosscrate.rs
 delete mode 100644 src/test/run-pass/abi/extern/extern-pass-TwoU16s.rs
 delete mode 100644 src/test/run-pass/abi/extern/extern-pass-TwoU32s.rs
 delete mode 100644 src/test/run-pass/abi/extern/extern-pass-TwoU64s.rs
 delete mode 100644 src/test/run-pass/abi/extern/extern-pass-TwoU8s.rs
 delete mode 100644 src/test/run-pass/abi/extern/extern-pass-char.rs
 delete mode 100644 src/test/run-pass/abi/extern/extern-pass-double.rs
 delete mode 100644 src/test/run-pass/abi/extern/extern-pass-empty.rs
 delete mode 100644 src/test/run-pass/abi/extern/extern-pass-u32.rs
 delete mode 100644 src/test/run-pass/abi/extern/extern-pass-u64.rs
 delete mode 100644 src/test/run-pass/abi/extern/extern-return-TwoU16s.rs
 delete mode 100644 src/test/run-pass/abi/extern/extern-return-TwoU32s.rs
 delete mode 100644 src/test/run-pass/abi/extern/extern-return-TwoU64s.rs
 delete mode 100644 src/test/run-pass/abi/extern/extern-return-TwoU8s.rs
 delete mode 100644 src/test/run-pass/abi/foreign/auxiliary/foreign_lib.rs
 delete mode 100644 src/test/run-pass/abi/foreign/foreign-call-no-runtime.rs
 delete mode 100644 src/test/run-pass/abi/foreign/foreign-dupe.rs
 delete mode 100644 src/test/run-pass/abi/foreign/foreign-fn-with-byval.rs
 delete mode 100644 src/test/run-pass/abi/foreign/foreign-no-abi.rs
 delete mode 100644 src/test/run-pass/abi/invoke-external-foreign.rs
 delete mode 100644 src/test/run-pass/abi/issues/auxiliary/issue-25185-1.rs
 delete mode 100644 src/test/run-pass/abi/issues/auxiliary/issue-25185-2.rs
 delete mode 100644 src/test/run-pass/abi/issues/issue-25185.rs
 delete mode 100644 src/test/run-pass/abi/issues/issue-28676.rs
 delete mode 100644 src/test/run-pass/abi/lib-defaults.rs
 delete mode 100644 src/test/run-pass/abi/macros/macros-in-extern.rs
 delete mode 100644 src/test/run-pass/abi/mir/mir_codegen_calls_variadic.rs
 delete mode 100644 src/test/run-pass/abi/numbers-arithmetic/i128-ffi.rs
 delete mode 100644 src/test/run-pass/abi/proc_macro/auxiliary/test-macros.rs
 delete mode 100644 src/test/run-pass/abi/proc_macro/macros-in-extern.rs
 delete mode 100644 src/test/run-pass/abi/rfcs/rfc1717/library-override.rs
 delete mode 100644 src/test/run-pass/abi/segfault-no-out-of-stack.rs
 delete mode 100644 src/test/run-pass/abi/stack-probes-lto.rs
 delete mode 100644 src/test/run-pass/abi/stack-probes.rs
 delete mode 100644 src/test/run-pass/abi/statics/static-mut-foreign.rs
 delete mode 100644 src/test/run-pass/abi/structs-enums/struct-return.rs
 delete mode 100644 src/test/run-pass/abi/union/union-c-interop.rs
 delete mode 100644 src/test/run-pass/abi/variadic-ffi.rs

diff --git a/src/test/run-pass/abi/abi-sysv64-arg-passing.rs b/src/test/run-pass/abi/abi-sysv64-arg-passing.rs
deleted file mode 100644
index fdf0573b5e3ec..0000000000000
--- a/src/test/run-pass/abi/abi-sysv64-arg-passing.rs
+++ /dev/null
@@ -1,366 +0,0 @@
-// Checks if the "sysv64" calling convention behaves the same as the
-// "C" calling convention on platforms where both should be the same
-
-// This file contains versions of the following run-pass tests with
-// the calling convention changed to "sysv64"
-
-// cabi-int-widening
-// extern-pass-char
-// extern-pass-u32
-// extern-pass-u64
-// extern-pass-double
-// extern-pass-empty
-// extern-pass-TwoU8s
-// extern-pass-TwoU16s
-// extern-pass-TwoU32s
-// extern-pass-TwoU64s
-// extern-return-TwoU8s
-// extern-return-TwoU16s
-// extern-return-TwoU32s
-// extern-return-TwoU64s
-// foreign-fn-with-byval
-// issue-28676
-// issue-62350-sysv-neg-reg-counts
-// struct-return
-
-// ignore-android
-// ignore-arm
-// ignore-aarch64
-// ignore-windows
-
-// note: windows is ignored as rust_test_helpers does not have the sysv64 abi on windows
-
-#[allow(dead_code)]
-#[allow(improper_ctypes)]
-
-#[cfg(target_arch = "x86_64")]
-mod tests {
-    #[repr(C)]
-    #[derive(Copy, Clone, PartialEq, Debug)]
-    pub struct TwoU8s {
-        one: u8, two: u8
-    }
-
-    #[repr(C)]
-    #[derive(Copy, Clone, PartialEq, Debug)]
-    pub struct TwoU16s {
-        one: u16, two: u16
-    }
-
-    #[repr(C)]
-    #[derive(Copy, Clone, PartialEq, Debug)]
-    pub struct TwoU32s {
-        one: u32, two: u32
-    }
-
-    #[repr(C)]
-    #[derive(Copy, Clone, PartialEq, Debug)]
-    pub struct TwoU64s {
-        one: u64, two: u64
-    }
-
-    #[repr(C)]
-    pub struct ManyInts {
-        arg1: i8,
-        arg2: i16,
-        arg3: i32,
-        arg4: i16,
-        arg5: i8,
-        arg6: TwoU8s,
-    }
-
-    #[repr(C)]
-    pub struct Empty;
-
-    #[repr(C)]
-    #[derive(Copy, Clone)]
-    pub struct S {
-        x: u64,
-        y: u64,
-        z: u64,
-    }
-
-    #[repr(C)]
-    #[derive(Copy, Clone)]
-    pub struct Quad { a: u64, b: u64, c: u64, d: u64 }
-
-    #[derive(Copy, Clone)]
-    pub struct QuadFloats { a: f32, b: f32, c: f32, d: f32 }
-
-    #[repr(C)]
-    #[derive(Copy, Clone)]
-    pub struct Floats { a: f64, b: u8, c: f64 }
-
-    #[link(name = "rust_test_helpers", kind = "static")]
-    extern "sysv64" {
-        pub fn rust_int8_to_int32(_: i8) -> i32;
-        pub fn rust_dbg_extern_identity_u8(v: u8) -> u8;
-        pub fn rust_dbg_extern_identity_u32(v: u32) -> u32;
-        pub fn rust_dbg_extern_identity_u64(v: u64) -> u64;
-        pub fn rust_dbg_extern_identity_double(v: f64) -> f64;
-        pub fn rust_dbg_extern_empty_struct(v1: ManyInts, e: Empty, v2: ManyInts);
-        pub fn rust_dbg_extern_identity_TwoU8s(v: TwoU8s) -> TwoU8s;
-        pub fn rust_dbg_extern_identity_TwoU16s(v: TwoU16s) -> TwoU16s;
-        pub fn rust_dbg_extern_identity_TwoU32s(v: TwoU32s) -> TwoU32s;
-        pub fn rust_dbg_extern_identity_TwoU64s(v: TwoU64s) -> TwoU64s;
-        pub fn rust_dbg_extern_return_TwoU8s() -> TwoU8s;
-        pub fn rust_dbg_extern_return_TwoU16s() -> TwoU16s;
-        pub fn rust_dbg_extern_return_TwoU32s() -> TwoU32s;
-        pub fn rust_dbg_extern_return_TwoU64s() -> TwoU64s;
-        pub fn get_x(x: S) -> u64;
-        pub fn get_y(x: S) -> u64;
-        pub fn get_z(x: S) -> u64;
-        pub fn get_c_many_params(_: *const (), _: *const (),
-                                 _: *const (), _: *const (), f: Quad) -> u64;
-        pub fn get_c_exhaust_sysv64_ints(
-            _: *const (),
-            _: *const (),
-            _: *const (),
-            _: *const (),
-            _: *const (),
-            _: *const (),
-            _: *const (),
-            h: QuadFloats,
-        ) -> f32;
-        pub fn rust_dbg_abi_1(q: Quad) -> Quad;
-        pub fn rust_dbg_abi_2(f: Floats) -> Floats;
-    }
-
-    pub fn cabi_int_widening() {
-        let x = unsafe {
-            rust_int8_to_int32(-1)
-        };
-
-        assert!(x == -1);
-    }
-
-    pub fn extern_pass_char() {
-        unsafe {
-            assert_eq!(22, rust_dbg_extern_identity_u8(22));
-        }
-    }
-
-    pub fn extern_pass_u32() {
-        unsafe {
-            assert_eq!(22, rust_dbg_extern_identity_u32(22));
-        }
-    }
-
-    pub fn extern_pass_u64() {
-        unsafe {
-            assert_eq!(22, rust_dbg_extern_identity_u64(22));
-        }
-    }
-
-    pub fn extern_pass_double() {
-        unsafe {
-            assert_eq!(22.0_f64, rust_dbg_extern_identity_double(22.0_f64));
-        }
-    }
-
-    pub fn extern_pass_empty() {
-        unsafe {
-            let x = ManyInts {
-                arg1: 2,
-                arg2: 3,
-                arg3: 4,
-                arg4: 5,
-                arg5: 6,
-                arg6: TwoU8s { one: 7, two: 8, }
-            };
-            let y = ManyInts {
-                arg1: 1,
-                arg2: 2,
-                arg3: 3,
-                arg4: 4,
-                arg5: 5,
-                arg6: TwoU8s { one: 6, two: 7, }
-            };
-            let empty = Empty;
-            rust_dbg_extern_empty_struct(x, empty, y);
-        }
-    }
-
-    pub fn extern_pass_twou8s() {
-        unsafe {
-            let x = TwoU8s {one: 22, two: 23};
-            let y = rust_dbg_extern_identity_TwoU8s(x);
-            assert_eq!(x, y);
-        }
-    }
-
-    pub fn extern_pass_twou16s() {
-        unsafe {
-            let x = TwoU16s {one: 22, two: 23};
-            let y = rust_dbg_extern_identity_TwoU16s(x);
-            assert_eq!(x, y);
-        }
-    }
-
-    pub fn extern_pass_twou32s() {
-        unsafe {
-            let x = TwoU32s {one: 22, two: 23};
-            let y = rust_dbg_extern_identity_TwoU32s(x);
-            assert_eq!(x, y);
-        }
-    }
-
-    pub fn extern_pass_twou64s() {
-        unsafe {
-            let x = TwoU64s {one: 22, two: 23};
-            let y = rust_dbg_extern_identity_TwoU64s(x);
-            assert_eq!(x, y);
-        }
-    }
-
-    pub fn extern_return_twou8s() {
-        unsafe {
-            let y = rust_dbg_extern_return_TwoU8s();
-            assert_eq!(y.one, 10);
-            assert_eq!(y.two, 20);
-        }
-    }
-
-    pub fn extern_return_twou16s() {
-        unsafe {
-            let y = rust_dbg_extern_return_TwoU16s();
-            assert_eq!(y.one, 10);
-            assert_eq!(y.two, 20);
-        }
-    }
-
-    pub fn extern_return_twou32s() {
-        unsafe {
-            let y = rust_dbg_extern_return_TwoU32s();
-            assert_eq!(y.one, 10);
-            assert_eq!(y.two, 20);
-        }
-    }
-
-    pub fn extern_return_twou64s() {
-        unsafe {
-            let y = rust_dbg_extern_return_TwoU64s();
-            assert_eq!(y.one, 10);
-            assert_eq!(y.two, 20);
-        }
-    }
-
-    #[inline(never)]
-    fn indirect_call(func: unsafe extern "sysv64" fn(s: S) -> u64, s: S) -> u64 {
-        unsafe {
-            func(s)
-        }
-    }
-
-    pub fn foreign_fn_with_byval() {
-        let s = S { x: 1, y: 2, z: 3 };
-        assert_eq!(s.x, indirect_call(get_x, s));
-        assert_eq!(s.y, indirect_call(get_y, s));
-        assert_eq!(s.z, indirect_call(get_z, s));
-    }
-
-    fn test() {
-        use std::ptr;
-        unsafe {
-            let null = ptr::null();
-            let q = Quad {
-                a: 1,
-                b: 2,
-                c: 3,
-                d: 4
-            };
-            assert_eq!(get_c_many_params(null, null, null, null, q), q.c);
-        }
-    }
-
-    pub fn issue_28676() {
-        test();
-    }
-
-    fn test_62350() {
-        use std::ptr;
-        unsafe {
-            let null = ptr::null();
-            let q = QuadFloats {
-                a: 10.2,
-                b: 20.3,
-                c: 30.4,
-                d: 40.5
-            };
-            assert_eq!(
-                get_c_exhaust_sysv64_ints(null, null, null, null, null, null, null, q),
-                q.c,
-            );
-        }
-    }
-
-    pub fn issue_62350() {
-        test_62350();
-    }
-
-    fn test1() {
-        unsafe {
-            let q = Quad { a: 0xaaaa_aaaa_aaaa_aaaa,
-                     b: 0xbbbb_bbbb_bbbb_bbbb,
-                     c: 0xcccc_cccc_cccc_cccc,
-                     d: 0xdddd_dddd_dddd_dddd };
-            let qq = rust_dbg_abi_1(q);
-            println!("a: {:x}", qq.a as usize);
-            println!("b: {:x}", qq.b as usize);
-            println!("c: {:x}", qq.c as usize);
-            println!("d: {:x}", qq.d as usize);
-            assert_eq!(qq.a, q.c + 1);
-            assert_eq!(qq.b, q.d - 1);
-            assert_eq!(qq.c, q.a + 1);
-            assert_eq!(qq.d, q.b - 1);
-        }
-    }
-
-    fn test2() {
-        unsafe {
-            let f = Floats { a: 1.234567890e-15_f64,
-                     b: 0b_1010_1010,
-                     c: 1.0987654321e-15_f64 };
-            let ff = rust_dbg_abi_2(f);
-            println!("a: {}", ff.a as f64);
-            println!("b: {}", ff.b as usize);
-            println!("c: {}", ff.c as f64);
-            assert_eq!(ff.a, f.c + 1.0f64);
-            assert_eq!(ff.b, 0xff);
-            assert_eq!(ff.c, f.a - 1.0f64);
-        }
-    }
-
-    pub fn struct_return() {
-        test1();
-        test2();
-    }
-}
-
-#[cfg(target_arch = "x86_64")]
-fn main() {
-    use tests::*;
-    cabi_int_widening();
-    extern_pass_char();
-    extern_pass_u32();
-    extern_pass_u64();
-    extern_pass_double();
-    extern_pass_empty();
-    extern_pass_twou8s();
-    extern_pass_twou16s();
-    extern_pass_twou32s();
-    extern_pass_twou64s();
-    extern_return_twou8s();
-    extern_return_twou16s();
-    extern_return_twou32s();
-    extern_return_twou64s();
-    foreign_fn_with_byval();
-    issue_28676();
-    issue_62350();
-    struct_return();
-}
-
-#[cfg(not(target_arch = "x86_64"))]
-fn main() {
-
-}
diff --git a/src/test/run-pass/abi/abi-sysv64-register-usage.rs b/src/test/run-pass/abi/abi-sysv64-register-usage.rs
deleted file mode 100644
index a0d6e968252a2..0000000000000
--- a/src/test/run-pass/abi/abi-sysv64-register-usage.rs
+++ /dev/null
@@ -1,95 +0,0 @@
-// Checks if the correct registers are being used to pass arguments
-// when the sysv64 ABI is specified.
-
-// ignore-android
-// ignore-arm
-// ignore-aarch64
-
-#![feature(asm)]
-
-#[cfg(target_arch = "x86_64")]
-pub extern "sysv64" fn all_the_registers(rdi: i64, rsi: i64, rdx: i64,
-                                         rcx: i64, r8 : i64, r9 : i64,
-                                         xmm0: f32, xmm1: f32, xmm2: f32,
-                                         xmm3: f32, xmm4: f32, xmm5: f32,
-                                         xmm6: f32, xmm7: f32) -> i64 {
-    assert_eq!(rdi, 1);
-    assert_eq!(rsi, 2);
-    assert_eq!(rdx, 3);
-    assert_eq!(rcx, 4);
-    assert_eq!(r8,  5);
-    assert_eq!(r9,  6);
-    assert_eq!(xmm0, 1.0f32);
-    assert_eq!(xmm1, 2.0f32);
-    assert_eq!(xmm2, 4.0f32);
-    assert_eq!(xmm3, 8.0f32);
-    assert_eq!(xmm4, 16.0f32);
-    assert_eq!(xmm5, 32.0f32);
-    assert_eq!(xmm6, 64.0f32);
-    assert_eq!(xmm7, 128.0f32);
-    42
-}
-
-// this struct contains 8 i64's, while only 6 can be passed in registers.
-#[cfg(target_arch = "x86_64")]
-#[derive(PartialEq, Eq, Debug)]
-pub struct LargeStruct(i64, i64, i64, i64, i64, i64, i64, i64);
-
-#[cfg(target_arch = "x86_64")]
-#[inline(never)]
-pub extern "sysv64" fn large_struct_by_val(mut foo: LargeStruct) -> LargeStruct {
-    foo.0 *= 1;
-    foo.1 *= 2;
-    foo.2 *= 3;
-    foo.3 *= 4;
-    foo.4 *= 5;
-    foo.5 *= 6;
-    foo.6 *= 7;
-    foo.7 *= 8;
-    foo
-}
-
-#[cfg(target_arch = "x86_64")]
-pub fn main() {
-    let result: i64;
-    unsafe {
-        asm!("mov rdi, 1;
-              mov rsi, 2;
-              mov rdx, 3;
-              mov rcx, 4;
-              mov r8,  5;
-              mov r9,  6;
-              mov eax, 0x3F800000;
-              movd xmm0, eax;
-              mov eax, 0x40000000;
-              movd xmm1, eax;
-              mov eax, 0x40800000;
-              movd xmm2, eax;
-              mov eax, 0x41000000;
-              movd xmm3, eax;
-              mov eax, 0x41800000;
-              movd xmm4, eax;
-              mov eax, 0x42000000;
-              movd xmm5, eax;
-              mov eax, 0x42800000;
-              movd xmm6, eax;
-              mov eax, 0x43000000;
-              movd xmm7, eax;
-              call r10
-              "
-            : "={rax}"(result)
-            : "{r10}"(all_the_registers as usize)
-            : "rdi", "rsi", "rdx", "rcx", "r8", "r9", "r11", "cc", "memory"
-            : "intel", "alignstack"
-        )
-    }
-    assert_eq!(result, 42);
-
-    assert_eq!(
-        large_struct_by_val(LargeStruct(1, 2, 3, 4, 5, 6, 7, 8)),
-        LargeStruct(1, 4, 9, 16, 25, 36, 49, 64)
-    );
-}
-
-#[cfg(not(target_arch = "x86_64"))]
-pub fn main() {}
diff --git a/src/test/run-pass/abi/abort-on-c-abi.rs b/src/test/run-pass/abi/abort-on-c-abi.rs
deleted file mode 100644
index 110f3eee1ef81..0000000000000
--- a/src/test/run-pass/abi/abort-on-c-abi.rs
+++ /dev/null
@@ -1,36 +0,0 @@
-#![allow(unused_must_use)]
-// Since we mark some ABIs as "nounwind" to LLVM, we must make sure that
-// we never unwind through them.
-
-// ignore-cloudabi no env and process
-// ignore-emscripten no processes
-// ignore-sgx no processes
-
-use std::{env, panic};
-use std::io::prelude::*;
-use std::io;
-use std::process::{Command, Stdio};
-
-extern "C" fn panic_in_ffi() {
-    panic!("Test");
-}
-
-fn test() {
-    let _ = panic::catch_unwind(|| { panic_in_ffi(); });
-    // The process should have aborted by now.
-    io::stdout().write(b"This should never be printed.\n");
-    let _ = io::stdout().flush();
-}
-
-fn main() {
-    let args: Vec<String> = env::args().collect();
-    if args.len() > 1 && args[1] == "test" {
-        return test();
-    }
-
-    let mut p = Command::new(&args[0])
-                        .stdout(Stdio::piped())
-                        .stdin(Stdio::piped())
-                        .arg("test").spawn().unwrap();
-    assert!(!p.wait().unwrap().success());
-}
diff --git a/src/test/run-pass/abi/anon-extern-mod.rs b/src/test/run-pass/abi/anon-extern-mod.rs
deleted file mode 100644
index 6d7e3f3cd5c1a..0000000000000
--- a/src/test/run-pass/abi/anon-extern-mod.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-// pretty-expanded FIXME #23616
-// ignore-wasm32-bare no libc to test ffi with
-
-#![feature(rustc_private)]
-
-extern crate libc;
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern {
-    fn rust_get_test_int() -> libc::intptr_t;
-}
-
-pub fn main() {
-    unsafe {
-        let _ = rust_get_test_int();
-    }
-}
diff --git a/src/test/run-pass/abi/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/run-pass/abi/auxiliary/anon-extern-mod-cross-crate-1.rs
deleted file mode 100644
index 948b5e688ebcc..0000000000000
--- a/src/test/run-pass/abi/auxiliary/anon-extern-mod-cross-crate-1.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-#![crate_name="anonexternmod"]
-#![feature(rustc_private)]
-
-extern crate libc;
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern {
-    pub fn rust_get_test_int() -> libc::intptr_t;
-}
diff --git a/src/test/run-pass/abi/auxiliary/foreign_lib.rs b/src/test/run-pass/abi/auxiliary/foreign_lib.rs
deleted file mode 100644
index de6b0e2118a58..0000000000000
--- a/src/test/run-pass/abi/auxiliary/foreign_lib.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-#![crate_name="foreign_lib"]
-
-#![feature(rustc_private)]
-
-pub mod rustrt {
-    extern crate libc;
-
-    #[link(name = "rust_test_helpers", kind = "static")]
-    extern {
-        pub fn rust_get_test_int() -> libc::intptr_t;
-    }
-}
-
-pub mod rustrt2 {
-    extern crate libc;
-
-    extern {
-        pub fn rust_get_test_int() -> libc::intptr_t;
-    }
-}
-
-pub mod rustrt3 {
-    // Different type, but same ABI (on all supported platforms).
-    // Ensures that we don't ICE or trigger LLVM asserts when
-    // importing the same symbol under different types.
-    // See https://github.com/rust-lang/rust/issues/32740.
-    extern {
-        pub fn rust_get_test_int() -> *const u8;
-    }
-}
-
-pub fn local_uses() {
-    unsafe {
-        let x = rustrt::rust_get_test_int();
-        assert_eq!(x, rustrt2::rust_get_test_int());
-        assert_eq!(x as *const _, rustrt3::rust_get_test_int());
-    }
-}
diff --git a/src/test/run-pass/abi/c-stack-as-value.rs b/src/test/run-pass/abi/c-stack-as-value.rs
deleted file mode 100644
index 3b997295c122a..0000000000000
--- a/src/test/run-pass/abi/c-stack-as-value.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-// pretty-expanded FIXME #23616
-// ignore-wasm32-bare no libc to test ffi with
-
-#![feature(rustc_private)]
-
-mod rustrt {
-    extern crate libc;
-
-    #[link(name = "rust_test_helpers", kind = "static")]
-    extern {
-        pub fn rust_get_test_int() -> libc::intptr_t;
-    }
-}
-
-pub fn main() {
-    let _foo = rustrt::rust_get_test_int;
-}
diff --git a/src/test/run-pass/abi/cabi-int-widening.rs b/src/test/run-pass/abi/cabi-int-widening.rs
deleted file mode 100644
index f6524c6a3d902..0000000000000
--- a/src/test/run-pass/abi/cabi-int-widening.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-// ignore-wasm32-bare no libc to test ffi with
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern {
-    fn rust_int8_to_int32(_: i8) -> i32;
-}
-
-fn main() {
-    let x = unsafe {
-        rust_int8_to_int32(-1)
-    };
-
-    assert!(x == -1);
-}
diff --git a/src/test/run-pass/abi/consts/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/run-pass/abi/consts/auxiliary/anon-extern-mod-cross-crate-1.rs
deleted file mode 100644
index 948b5e688ebcc..0000000000000
--- a/src/test/run-pass/abi/consts/auxiliary/anon-extern-mod-cross-crate-1.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-#![crate_name="anonexternmod"]
-#![feature(rustc_private)]
-
-extern crate libc;
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern {
-    pub fn rust_get_test_int() -> libc::intptr_t;
-}
diff --git a/src/test/run-pass/abi/cross-crate/anon-extern-mod-cross-crate-2.rs b/src/test/run-pass/abi/cross-crate/anon-extern-mod-cross-crate-2.rs
deleted file mode 100644
index 77168be5374b2..0000000000000
--- a/src/test/run-pass/abi/cross-crate/anon-extern-mod-cross-crate-2.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-// run-pass
-// aux-build:anon-extern-mod-cross-crate-1.rs
-// pretty-expanded FIXME #23616
-// ignore-wasm32-bare no libc to test ffi with
-
-extern crate anonexternmod;
-
-use anonexternmod::rust_get_test_int;
-
-pub fn main() {
-    unsafe {
-        rust_get_test_int();
-    }
-}
diff --git a/src/test/run-pass/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/run-pass/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs
deleted file mode 100644
index 948b5e688ebcc..0000000000000
--- a/src/test/run-pass/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-#![crate_name="anonexternmod"]
-#![feature(rustc_private)]
-
-extern crate libc;
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern {
-    pub fn rust_get_test_int() -> libc::intptr_t;
-}
diff --git a/src/test/run-pass/abi/duplicated-external-mods.rs b/src/test/run-pass/abi/duplicated-external-mods.rs
deleted file mode 100644
index f2c1e1f654016..0000000000000
--- a/src/test/run-pass/abi/duplicated-external-mods.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-// aux-build:anon-extern-mod-cross-crate-1.rs
-// aux-build:anon-extern-mod-cross-crate-1.rs
-// pretty-expanded FIXME #23616
-// ignore-wasm32-bare no libc to test ffi with
-
-extern crate anonexternmod;
-
-pub fn main() { }
diff --git a/src/test/run-pass/abi/extern/auxiliary/extern-crosscrate-source.rs b/src/test/run-pass/abi/extern/auxiliary/extern-crosscrate-source.rs
deleted file mode 100644
index d4568d38e25c9..0000000000000
--- a/src/test/run-pass/abi/extern/auxiliary/extern-crosscrate-source.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-#![crate_name="externcallback"]
-#![crate_type = "lib"]
-#![feature(rustc_private)]
-
-extern crate libc;
-
-pub mod rustrt {
-    extern crate libc;
-
-    #[link(name = "rust_test_helpers", kind = "static")]
-    extern {
-        pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t,
-                             data: libc::uintptr_t)
-                             -> libc::uintptr_t;
-    }
-}
-
-pub fn fact(n: libc::uintptr_t) -> libc::uintptr_t {
-    unsafe {
-        println!("n = {}", n);
-        rustrt::rust_dbg_call(cb, n)
-    }
-}
-
-pub extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
-    if data == 1 {
-        data
-    } else {
-        fact(data - 1) * data
-    }
-}
diff --git a/src/test/run-pass/abi/extern/extern-call-deep.rs b/src/test/run-pass/abi/extern/extern-call-deep.rs
deleted file mode 100644
index 81f884dada9b8..0000000000000
--- a/src/test/run-pass/abi/extern/extern-call-deep.rs
+++ /dev/null
@@ -1,39 +0,0 @@
-// run-pass
-// ignore-wasm32-bare no libc to test ffi with
-// ignore-emscripten blows the JS stack
-
-#![feature(rustc_private)]
-
-extern crate libc;
-
-mod rustrt {
-    extern crate libc;
-
-    #[link(name = "rust_test_helpers", kind = "static")]
-    extern {
-        pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t,
-                             data: libc::uintptr_t)
-                             -> libc::uintptr_t;
-    }
-}
-
-extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
-    if data == 1 {
-        data
-    } else {
-        count(data - 1) + 1
-    }
-}
-
-fn count(n: libc::uintptr_t) -> libc::uintptr_t {
-    unsafe {
-        println!("n = {}", n);
-        rustrt::rust_dbg_call(cb, n)
-    }
-}
-
-pub fn main() {
-    let result = count(1000);
-    println!("result = {}", result);
-    assert_eq!(result, 1000);
-}
diff --git a/src/test/run-pass/abi/extern/extern-call-deep2.rs b/src/test/run-pass/abi/extern/extern-call-deep2.rs
deleted file mode 100644
index b31489b1e10cc..0000000000000
--- a/src/test/run-pass/abi/extern/extern-call-deep2.rs
+++ /dev/null
@@ -1,44 +0,0 @@
-// run-pass
-#![allow(unused_must_use)]
-// ignore-emscripten no threads support
-
-#![feature(rustc_private)]
-
-extern crate libc;
-use std::thread;
-
-mod rustrt {
-    extern crate libc;
-
-    #[link(name = "rust_test_helpers", kind = "static")]
-    extern {
-        pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t,
-                             data: libc::uintptr_t)
-                             -> libc::uintptr_t;
-    }
-}
-
-extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
-    if data == 1 {
-        data
-    } else {
-        count(data - 1) + 1
-    }
-}
-
-fn count(n: libc::uintptr_t) -> libc::uintptr_t {
-    unsafe {
-        println!("n = {}", n);
-        rustrt::rust_dbg_call(cb, n)
-    }
-}
-
-pub fn main() {
-    // Make sure we're on a thread with small Rust stacks (main currently
-    // has a large stack)
-    thread::spawn(move|| {
-        let result = count(1000);
-        println!("result = {}", result);
-        assert_eq!(result, 1000);
-    }).join();
-}
diff --git a/src/test/run-pass/abi/extern/extern-call-indirect.rs b/src/test/run-pass/abi/extern/extern-call-indirect.rs
deleted file mode 100644
index 158b54e4b8cdd..0000000000000
--- a/src/test/run-pass/abi/extern/extern-call-indirect.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-// run-pass
-// ignore-wasm32-bare no libc to test ffi with
-
-#![feature(rustc_private)]
-
-extern crate libc;
-
-mod rustrt {
-    extern crate libc;
-
-    #[link(name = "rust_test_helpers", kind = "static")]
-    extern {
-        pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t,
-                             data: libc::uintptr_t)
-                             -> libc::uintptr_t;
-    }
-}
-
-extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
-    if data == 1 {
-        data
-    } else {
-        fact(data - 1) * data
-    }
-}
-
-fn fact(n: libc::uintptr_t) -> libc::uintptr_t {
-    unsafe {
-        println!("n = {}", n);
-        rustrt::rust_dbg_call(cb, n)
-    }
-}
-
-pub fn main() {
-    let result = fact(10);
-    println!("result = {}", result);
-    assert_eq!(result, 3628800);
-}
diff --git a/src/test/run-pass/abi/extern/extern-call-scrub.rs b/src/test/run-pass/abi/extern/extern-call-scrub.rs
deleted file mode 100644
index a7b1065c9e1f6..0000000000000
--- a/src/test/run-pass/abi/extern/extern-call-scrub.rs
+++ /dev/null
@@ -1,48 +0,0 @@
-// run-pass
-#![allow(unused_must_use)]
-// This time we're testing repeatedly going up and down both stacks to
-// make sure the stack pointers are maintained properly in both
-// directions
-
-// ignore-emscripten no threads support
-
-#![feature(rustc_private)]
-
-extern crate libc;
-use std::thread;
-
-mod rustrt {
-    extern crate libc;
-
-    #[link(name = "rust_test_helpers", kind = "static")]
-    extern {
-        pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t,
-                             data: libc::uintptr_t)
-                             -> libc::uintptr_t;
-    }
-}
-
-extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
-    if data == 1 {
-        data
-    } else {
-        count(data - 1) + count(data - 1)
-    }
-}
-
-fn count(n: libc::uintptr_t) -> libc::uintptr_t {
-    unsafe {
-        println!("n = {}", n);
-        rustrt::rust_dbg_call(cb, n)
-    }
-}
-
-pub fn main() {
-    // Make sure we're on a thread with small Rust stacks (main currently
-    // has a large stack)
-    thread::spawn(move|| {
-        let result = count(12);
-        println!("result = {}", result);
-        assert_eq!(result, 2048);
-    }).join();
-}
diff --git a/src/test/run-pass/abi/extern/extern-crosscrate.rs b/src/test/run-pass/abi/extern/extern-crosscrate.rs
deleted file mode 100644
index 123ce20ca262f..0000000000000
--- a/src/test/run-pass/abi/extern/extern-crosscrate.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-// run-pass
-// aux-build:extern-crosscrate-source.rs
-// ignore-wasm32-bare no libc to test ffi with
-
-#![feature(rustc_private)]
-
-extern crate externcallback;
-extern crate libc;
-
-fn fact(n: libc::uintptr_t) -> libc::uintptr_t {
-    unsafe {
-        println!("n = {}", n);
-        externcallback::rustrt::rust_dbg_call(externcallback::cb, n)
-    }
-}
-
-pub fn main() {
-    let result = fact(10);
-    println!("result = {}", result);
-    assert_eq!(result, 3628800);
-}
diff --git a/src/test/run-pass/abi/extern/extern-pass-TwoU16s.rs b/src/test/run-pass/abi/extern/extern-pass-TwoU16s.rs
deleted file mode 100644
index 285bce2e19c31..0000000000000
--- a/src/test/run-pass/abi/extern/extern-pass-TwoU16s.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-// run-pass
-#![allow(improper_ctypes)]
-
-// ignore-wasm32-bare no libc for ffi testing
-
-// Test a foreign function that accepts and returns a struct
-// by value.
-
-#[derive(Copy, Clone, PartialEq, Debug)]
-pub struct TwoU16s {
-    one: u16, two: u16
-}
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern {
-    pub fn rust_dbg_extern_identity_TwoU16s(v: TwoU16s) -> TwoU16s;
-}
-
-pub fn main() {
-    unsafe {
-        let x = TwoU16s {one: 22, two: 23};
-        let y = rust_dbg_extern_identity_TwoU16s(x);
-        assert_eq!(x, y);
-    }
-}
diff --git a/src/test/run-pass/abi/extern/extern-pass-TwoU32s.rs b/src/test/run-pass/abi/extern/extern-pass-TwoU32s.rs
deleted file mode 100644
index fb18aa8d22fda..0000000000000
--- a/src/test/run-pass/abi/extern/extern-pass-TwoU32s.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-// run-pass
-#![allow(improper_ctypes)]
-
-// ignore-wasm32-bare no libc for ffi testing
-
-// Test a foreign function that accepts and returns a struct
-// by value.
-
-#[derive(Copy, Clone, PartialEq, Debug)]
-pub struct TwoU32s {
-    one: u32, two: u32
-}
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern {
-    pub fn rust_dbg_extern_identity_TwoU32s(v: TwoU32s) -> TwoU32s;
-}
-
-pub fn main() {
-    unsafe {
-        let x = TwoU32s {one: 22, two: 23};
-        let y = rust_dbg_extern_identity_TwoU32s(x);
-        assert_eq!(x, y);
-    }
-}
diff --git a/src/test/run-pass/abi/extern/extern-pass-TwoU64s.rs b/src/test/run-pass/abi/extern/extern-pass-TwoU64s.rs
deleted file mode 100644
index 419648263aa9b..0000000000000
--- a/src/test/run-pass/abi/extern/extern-pass-TwoU64s.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-// run-pass
-#![allow(improper_ctypes)]
-
-// ignore-wasm32-bare no libc for ffi testing
-
-// Test a foreign function that accepts and returns a struct
-// by value.
-
-#[derive(Copy, Clone, PartialEq, Debug)]
-pub struct TwoU64s {
-    one: u64, two: u64
-}
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern {
-    pub fn rust_dbg_extern_identity_TwoU64s(v: TwoU64s) -> TwoU64s;
-}
-
-pub fn main() {
-    unsafe {
-        let x = TwoU64s {one: 22, two: 23};
-        let y = rust_dbg_extern_identity_TwoU64s(x);
-        assert_eq!(x, y);
-    }
-}
diff --git a/src/test/run-pass/abi/extern/extern-pass-TwoU8s.rs b/src/test/run-pass/abi/extern/extern-pass-TwoU8s.rs
deleted file mode 100644
index 53a6a0f29f8a6..0000000000000
--- a/src/test/run-pass/abi/extern/extern-pass-TwoU8s.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-// run-pass
-#![allow(improper_ctypes)]
-
-// ignore-wasm32-bare no libc for ffi testing
-
-// Test a foreign function that accepts and returns a struct
-// by value.
-
-#[derive(Copy, Clone, PartialEq, Debug)]
-pub struct TwoU8s {
-    one: u8, two: u8
-}
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern {
-    pub fn rust_dbg_extern_identity_TwoU8s(v: TwoU8s) -> TwoU8s;
-}
-
-pub fn main() {
-    unsafe {
-        let x = TwoU8s {one: 22, two: 23};
-        let y = rust_dbg_extern_identity_TwoU8s(x);
-        assert_eq!(x, y);
-    }
-}
diff --git a/src/test/run-pass/abi/extern/extern-pass-char.rs b/src/test/run-pass/abi/extern/extern-pass-char.rs
deleted file mode 100644
index 22f841b45527e..0000000000000
--- a/src/test/run-pass/abi/extern/extern-pass-char.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-// run-pass
-// ignore-wasm32-bare no libc for ffi testing
-
-// Test a function that takes/returns a u8.
-
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern {
-    pub fn rust_dbg_extern_identity_u8(v: u8) -> u8;
-}
-
-pub fn main() {
-    unsafe {
-        assert_eq!(22, rust_dbg_extern_identity_u8(22));
-    }
-}
diff --git a/src/test/run-pass/abi/extern/extern-pass-double.rs b/src/test/run-pass/abi/extern/extern-pass-double.rs
deleted file mode 100644
index dbd0a2dfa4889..0000000000000
--- a/src/test/run-pass/abi/extern/extern-pass-double.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-// run-pass
-// ignore-wasm32-bare no libc for ffi testing
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern {
-    pub fn rust_dbg_extern_identity_double(v: f64) -> f64;
-}
-
-pub fn main() {
-    unsafe {
-        assert_eq!(22.0_f64, rust_dbg_extern_identity_double(22.0_f64));
-    }
-}
diff --git a/src/test/run-pass/abi/extern/extern-pass-empty.rs b/src/test/run-pass/abi/extern/extern-pass-empty.rs
deleted file mode 100644
index 07099a2420483..0000000000000
--- a/src/test/run-pass/abi/extern/extern-pass-empty.rs
+++ /dev/null
@@ -1,55 +0,0 @@
-// run-pass
-#![allow(improper_ctypes)] // FIXME: this test is inherently not FFI-safe.
-
-// Test a foreign function that accepts empty struct.
-
-// pretty-expanded FIXME #23616
-// ignore-msvc
-// ignore-emscripten emcc asserts on an empty struct as an argument
-
-#[repr(C)]
-struct TwoU8s {
-    one: u8,
-    two: u8,
-}
-
-#[repr(C)]
-struct ManyInts {
-    arg1: i8,
-    arg2: i16,
-    arg3: i32,
-    arg4: i16,
-    arg5: i8,
-    arg6: TwoU8s,
-}
-
-#[repr(C)]
-struct Empty;
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern {
-    fn rust_dbg_extern_empty_struct(v1: ManyInts, e: Empty, v2: ManyInts);
-}
-
-pub fn main() {
-    unsafe {
-        let x = ManyInts {
-            arg1: 2,
-            arg2: 3,
-            arg3: 4,
-            arg4: 5,
-            arg5: 6,
-            arg6: TwoU8s { one: 7, two: 8, }
-        };
-        let y = ManyInts {
-            arg1: 1,
-            arg2: 2,
-            arg3: 3,
-            arg4: 4,
-            arg5: 5,
-            arg6: TwoU8s { one: 6, two: 7, }
-        };
-        let empty = Empty;
-        rust_dbg_extern_empty_struct(x, empty, y);
-    }
-}
diff --git a/src/test/run-pass/abi/extern/extern-pass-u32.rs b/src/test/run-pass/abi/extern/extern-pass-u32.rs
deleted file mode 100644
index f2efdb7d3664e..0000000000000
--- a/src/test/run-pass/abi/extern/extern-pass-u32.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-// run-pass
-// ignore-wasm32-bare no libc for ffi testing
-
-// Test a function that takes/returns a u32.
-
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern {
-    pub fn rust_dbg_extern_identity_u32(v: u32) -> u32;
-}
-
-pub fn main() {
-    unsafe {
-        assert_eq!(22, rust_dbg_extern_identity_u32(22));
-    }
-}
diff --git a/src/test/run-pass/abi/extern/extern-pass-u64.rs b/src/test/run-pass/abi/extern/extern-pass-u64.rs
deleted file mode 100644
index 975446d430c28..0000000000000
--- a/src/test/run-pass/abi/extern/extern-pass-u64.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-// run-pass
-// ignore-wasm32-bare no libc for ffi testing
-
-// Test a call to a function that takes/returns a u64.
-
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern {
-    pub fn rust_dbg_extern_identity_u64(v: u64) -> u64;
-}
-
-pub fn main() {
-    unsafe {
-        assert_eq!(22, rust_dbg_extern_identity_u64(22));
-    }
-}
diff --git a/src/test/run-pass/abi/extern/extern-return-TwoU16s.rs b/src/test/run-pass/abi/extern/extern-return-TwoU16s.rs
deleted file mode 100644
index dd884ee77fe77..0000000000000
--- a/src/test/run-pass/abi/extern/extern-return-TwoU16s.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-// run-pass
-#![allow(improper_ctypes)]
-
-// ignore-wasm32-bare no libc to test ffi with
-
-pub struct TwoU16s {
-    one: u16, two: u16
-}
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern {
-    pub fn rust_dbg_extern_return_TwoU16s() -> TwoU16s;
-}
-
-pub fn main() {
-    unsafe {
-        let y = rust_dbg_extern_return_TwoU16s();
-        assert_eq!(y.one, 10);
-        assert_eq!(y.two, 20);
-    }
-}
diff --git a/src/test/run-pass/abi/extern/extern-return-TwoU32s.rs b/src/test/run-pass/abi/extern/extern-return-TwoU32s.rs
deleted file mode 100644
index d6aaf5c9eaf1b..0000000000000
--- a/src/test/run-pass/abi/extern/extern-return-TwoU32s.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-// run-pass
-#![allow(improper_ctypes)]
-
-// ignore-wasm32-bare no libc to test ffi with
-
-pub struct TwoU32s {
-    one: u32, two: u32
-}
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern {
-    pub fn rust_dbg_extern_return_TwoU32s() -> TwoU32s;
-}
-
-pub fn main() {
-    unsafe {
-        let y = rust_dbg_extern_return_TwoU32s();
-        assert_eq!(y.one, 10);
-        assert_eq!(y.two, 20);
-    }
-}
diff --git a/src/test/run-pass/abi/extern/extern-return-TwoU64s.rs b/src/test/run-pass/abi/extern/extern-return-TwoU64s.rs
deleted file mode 100644
index c5e4ebadc182a..0000000000000
--- a/src/test/run-pass/abi/extern/extern-return-TwoU64s.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-// run-pass
-#![allow(improper_ctypes)]
-
-// ignore-wasm32-bare no libc to test ffi with
-
-pub struct TwoU64s {
-    one: u64, two: u64
-}
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern {
-    pub fn rust_dbg_extern_return_TwoU64s() -> TwoU64s;
-}
-
-pub fn main() {
-    unsafe {
-        let y = rust_dbg_extern_return_TwoU64s();
-        assert_eq!(y.one, 10);
-        assert_eq!(y.two, 20);
-    }
-}
diff --git a/src/test/run-pass/abi/extern/extern-return-TwoU8s.rs b/src/test/run-pass/abi/extern/extern-return-TwoU8s.rs
deleted file mode 100644
index a7cd21b207359..0000000000000
--- a/src/test/run-pass/abi/extern/extern-return-TwoU8s.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-// run-pass
-#![allow(improper_ctypes)]
-
-// ignore-wasm32-bare no libc to test ffi with
-
-pub struct TwoU8s {
-    one: u8, two: u8
-}
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern {
-    pub fn rust_dbg_extern_return_TwoU8s() -> TwoU8s;
-}
-
-pub fn main() {
-    unsafe {
-        let y = rust_dbg_extern_return_TwoU8s();
-        assert_eq!(y.one, 10);
-        assert_eq!(y.two, 20);
-    }
-}
diff --git a/src/test/run-pass/abi/foreign/auxiliary/foreign_lib.rs b/src/test/run-pass/abi/foreign/auxiliary/foreign_lib.rs
deleted file mode 100644
index de6b0e2118a58..0000000000000
--- a/src/test/run-pass/abi/foreign/auxiliary/foreign_lib.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-#![crate_name="foreign_lib"]
-
-#![feature(rustc_private)]
-
-pub mod rustrt {
-    extern crate libc;
-
-    #[link(name = "rust_test_helpers", kind = "static")]
-    extern {
-        pub fn rust_get_test_int() -> libc::intptr_t;
-    }
-}
-
-pub mod rustrt2 {
-    extern crate libc;
-
-    extern {
-        pub fn rust_get_test_int() -> libc::intptr_t;
-    }
-}
-
-pub mod rustrt3 {
-    // Different type, but same ABI (on all supported platforms).
-    // Ensures that we don't ICE or trigger LLVM asserts when
-    // importing the same symbol under different types.
-    // See https://github.com/rust-lang/rust/issues/32740.
-    extern {
-        pub fn rust_get_test_int() -> *const u8;
-    }
-}
-
-pub fn local_uses() {
-    unsafe {
-        let x = rustrt::rust_get_test_int();
-        assert_eq!(x, rustrt2::rust_get_test_int());
-        assert_eq!(x as *const _, rustrt3::rust_get_test_int());
-    }
-}
diff --git a/src/test/run-pass/abi/foreign/foreign-call-no-runtime.rs b/src/test/run-pass/abi/foreign/foreign-call-no-runtime.rs
deleted file mode 100644
index c6afa07ad0503..0000000000000
--- a/src/test/run-pass/abi/foreign/foreign-call-no-runtime.rs
+++ /dev/null
@@ -1,55 +0,0 @@
-// run-pass
-// ignore-emscripten no threads support
-
-#![feature(rustc_private)]
-
-extern crate libc;
-
-use std::mem;
-use std::thread;
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern {
-    fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t),
-                     data: libc::uintptr_t) -> libc::uintptr_t;
-}
-
-pub fn main() {
-    unsafe {
-        thread::spawn(move|| {
-            let i: isize = 100;
-            rust_dbg_call(callback_isize, mem::transmute(&i));
-        }).join().unwrap();
-
-        thread::spawn(move|| {
-            let i: i32 = 100;
-            rust_dbg_call(callback_i32, mem::transmute(&i));
-        }).join().unwrap();
-
-        thread::spawn(move|| {
-            let i: i64 = 100;
-            rust_dbg_call(callback_i64, mem::transmute(&i));
-        }).join().unwrap();
-    }
-}
-
-extern fn callback_isize(data: libc::uintptr_t) {
-    unsafe {
-        let data: *const isize = mem::transmute(data);
-        assert_eq!(*data, 100);
-    }
-}
-
-extern fn callback_i64(data: libc::uintptr_t) {
-    unsafe {
-        let data: *const i64 = mem::transmute(data);
-        assert_eq!(*data, 100);
-    }
-}
-
-extern fn callback_i32(data: libc::uintptr_t) {
-    unsafe {
-        let data: *const i32 = mem::transmute(data);
-        assert_eq!(*data, 100);
-    }
-}
diff --git a/src/test/run-pass/abi/foreign/foreign-dupe.rs b/src/test/run-pass/abi/foreign/foreign-dupe.rs
deleted file mode 100644
index 3c9f0f583d487..0000000000000
--- a/src/test/run-pass/abi/foreign/foreign-dupe.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-// run-pass
-// aux-build:foreign_lib.rs
-// ignore-wasm32-bare no libc to test ffi with
-
-// Check that we can still call duplicated extern (imported) functions
-// which were declared in another crate. See issues #32740 and #32783.
-
-
-extern crate foreign_lib;
-
-pub fn main() {
-    unsafe {
-        let x = foreign_lib::rustrt::rust_get_test_int();
-        assert_eq!(x, foreign_lib::rustrt2::rust_get_test_int());
-        assert_eq!(x as *const _, foreign_lib::rustrt3::rust_get_test_int());
-    }
-}
diff --git a/src/test/run-pass/abi/foreign/foreign-fn-with-byval.rs b/src/test/run-pass/abi/foreign/foreign-fn-with-byval.rs
deleted file mode 100644
index 3a35599aa573f..0000000000000
--- a/src/test/run-pass/abi/foreign/foreign-fn-with-byval.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-// run-pass
-#![allow(improper_ctypes)]
-
-// ignore-wasm32-bare no libc to test ffi with
-
-#[derive(Copy, Clone)]
-pub struct S {
-    x: u64,
-    y: u64,
-    z: u64,
-}
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern {
-    pub fn get_x(x: S) -> u64;
-    pub fn get_y(x: S) -> u64;
-    pub fn get_z(x: S) -> u64;
-}
-
-#[inline(never)]
-fn indirect_call(func: unsafe extern fn(s: S) -> u64, s: S) -> u64 {
-    unsafe {
-        func(s)
-    }
-}
-
-fn main() {
-    let s = S { x: 1, y: 2, z: 3 };
-    assert_eq!(s.x, indirect_call(get_x, s));
-    assert_eq!(s.y, indirect_call(get_y, s));
-    assert_eq!(s.z, indirect_call(get_z, s));
-}
diff --git a/src/test/run-pass/abi/foreign/foreign-no-abi.rs b/src/test/run-pass/abi/foreign/foreign-no-abi.rs
deleted file mode 100644
index 2f33fb4765690..0000000000000
--- a/src/test/run-pass/abi/foreign/foreign-no-abi.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-// run-pass
-// ABI is cdecl by default
-
-// ignore-wasm32-bare no libc to test ffi with
-// pretty-expanded FIXME #23616
-
-#![feature(rustc_private)]
-
-mod rustrt {
-    extern crate libc;
-
-    #[link(name = "rust_test_helpers", kind = "static")]
-    extern {
-        pub fn rust_get_test_int() -> libc::intptr_t;
-    }
-}
-
-pub fn main() {
-    unsafe {
-        rustrt::rust_get_test_int();
-    }
-}
diff --git a/src/test/run-pass/abi/invoke-external-foreign.rs b/src/test/run-pass/abi/invoke-external-foreign.rs
deleted file mode 100644
index d34933cde4246..0000000000000
--- a/src/test/run-pass/abi/invoke-external-foreign.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-// aux-build:foreign_lib.rs
-// ignore-wasm32-bare no libc to test ffi with
-
-// The purpose of this test is to check that we can
-// successfully (and safely) invoke external, cdecl
-// functions from outside the crate.
-
-// pretty-expanded FIXME #23616
-
-extern crate foreign_lib;
-
-pub fn main() {
-    unsafe {
-        let _foo = foreign_lib::rustrt::rust_get_test_int();
-    }
-}
diff --git a/src/test/run-pass/abi/issues/auxiliary/issue-25185-1.rs b/src/test/run-pass/abi/issues/auxiliary/issue-25185-1.rs
deleted file mode 100644
index 77a4787ba943d..0000000000000
--- a/src/test/run-pass/abi/issues/auxiliary/issue-25185-1.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-// no-prefer-dynamic
-
-#![crate_type = "rlib"]
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern {
-    pub fn rust_dbg_extern_identity_u32(u: u32) -> u32;
-}
diff --git a/src/test/run-pass/abi/issues/auxiliary/issue-25185-2.rs b/src/test/run-pass/abi/issues/auxiliary/issue-25185-2.rs
deleted file mode 100644
index 7ce3df255a331..0000000000000
--- a/src/test/run-pass/abi/issues/auxiliary/issue-25185-2.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-extern crate issue_25185_1;
-
-pub use issue_25185_1::rust_dbg_extern_identity_u32;
diff --git a/src/test/run-pass/abi/issues/issue-25185.rs b/src/test/run-pass/abi/issues/issue-25185.rs
deleted file mode 100644
index 383c9a1e9c4ab..0000000000000
--- a/src/test/run-pass/abi/issues/issue-25185.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-// run-pass
-// aux-build:issue-25185-1.rs
-// aux-build:issue-25185-2.rs
-// ignore-wasm32-bare no libc for ffi testing
-
-extern crate issue_25185_2;
-
-fn main() {
-    let x = unsafe {
-        issue_25185_2::rust_dbg_extern_identity_u32(1)
-    };
-    assert_eq!(x, 1);
-}
diff --git a/src/test/run-pass/abi/issues/issue-28676.rs b/src/test/run-pass/abi/issues/issue-28676.rs
deleted file mode 100644
index 2b83478ca6115..0000000000000
--- a/src/test/run-pass/abi/issues/issue-28676.rs
+++ /dev/null
@@ -1,35 +0,0 @@
-// run-pass
-#![allow(dead_code)]
-#![allow(improper_ctypes)]
-
-// ignore-wasm32-bare no libc to test ffi with
-
-#[derive(Copy, Clone)]
-pub struct Quad { a: u64, b: u64, c: u64, d: u64 }
-
-mod rustrt {
-    use super::Quad;
-
-    #[link(name = "rust_test_helpers", kind = "static")]
-    extern {
-        pub fn get_c_many_params(_: *const (), _: *const (),
-                                 _: *const (), _: *const (), f: Quad) -> u64;
-    }
-}
-
-fn test() {
-    unsafe {
-        let null = std::ptr::null();
-        let q = Quad {
-            a: 1,
-            b: 2,
-            c: 3,
-            d: 4
-        };
-        assert_eq!(rustrt::get_c_many_params(null, null, null, null, q), q.c);
-    }
-}
-
-pub fn main() {
-    test();
-}
diff --git a/src/test/run-pass/abi/lib-defaults.rs b/src/test/run-pass/abi/lib-defaults.rs
deleted file mode 100644
index dcf537866c50b..0000000000000
--- a/src/test/run-pass/abi/lib-defaults.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-// dont-check-compiler-stderr (rust-lang/rust#54222)
-
-// ignore-wasm32-bare no libc to test ffi with
-
-// compile-flags: -lrust_test_helpers
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern "C" {
-    pub fn rust_dbg_extern_identity_u32(x: u32) -> u32;
-}
-
-fn main() {
-    unsafe {
-        rust_dbg_extern_identity_u32(42);
-    }
-}
diff --git a/src/test/run-pass/abi/macros/macros-in-extern.rs b/src/test/run-pass/abi/macros/macros-in-extern.rs
deleted file mode 100644
index 28abef5cf4edc..0000000000000
--- a/src/test/run-pass/abi/macros/macros-in-extern.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-// run-pass
-// ignore-wasm32
-
-#![feature(decl_macro, macros_in_extern)]
-
-macro_rules! returns_isize(
-    ($ident:ident) => (
-        fn $ident() -> isize;
-    )
-);
-
-macro takes_u32_returns_u32($ident:ident) {
-    fn $ident (arg: u32) -> u32;
-}
-
-macro_rules! emits_nothing(
-    () => ()
-);
-
-fn main() {
-    assert_eq!(unsafe { rust_get_test_int() }, 1isize);
-    assert_eq!(unsafe { rust_dbg_extern_identity_u32(0xDEADBEEF) }, 0xDEADBEEFu32);
-}
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern {
-    returns_isize!(rust_get_test_int);
-    takes_u32_returns_u32!(rust_dbg_extern_identity_u32);
-    emits_nothing!();
-}
diff --git a/src/test/run-pass/abi/mir/mir_codegen_calls_variadic.rs b/src/test/run-pass/abi/mir/mir_codegen_calls_variadic.rs
deleted file mode 100644
index dc9fee03b776c..0000000000000
--- a/src/test/run-pass/abi/mir/mir_codegen_calls_variadic.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-// run-pass
-// ignore-wasm32-bare no libc to test ffi with
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern {
-    fn rust_interesting_average(_: i64, ...) -> f64;
-}
-
-fn test<T, U>(a: i64, b: i64, c: i64, d: i64, e: i64, f: T, g: U) -> i64 {
-    unsafe {
-        rust_interesting_average(6, a, a as f64,
-                                    b, b as f64,
-                                    c, c as f64,
-                                    d, d as f64,
-                                    e, e as f64,
-                                    f, g) as i64
-    }
-}
-
-fn main(){
-    assert_eq!(test(10, 20, 30, 40, 50, 60_i64, 60.0_f64), 70);
-}
diff --git a/src/test/run-pass/abi/numbers-arithmetic/i128-ffi.rs b/src/test/run-pass/abi/numbers-arithmetic/i128-ffi.rs
deleted file mode 100644
index 19edf9779f35e..0000000000000
--- a/src/test/run-pass/abi/numbers-arithmetic/i128-ffi.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-// run-pass
-#![allow(improper_ctypes)]
-
-// MSVC doesn't support 128 bit integers, and other Windows
-// C compilers have very inconsistent views on how the ABI
-// should look like.
-
-// ignore-windows
-// ignore-32bit
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern "C" {
-    fn identity(f: u128) -> u128;
-    fn square(f: i128) -> i128;
-    fn sub(f: i128, f: i128) -> i128;
-}
-
-fn main() {
-    unsafe {
-        let a = 0x734C_C2F2_A521;
-        let b = 0x33EE_0E2A_54E2_59DA_A0E7_8E41;
-        let b_out = identity(b);
-        assert_eq!(b, b_out);
-        let a_square = square(a);
-        assert_eq!(b, a_square as u128);
-        let k = 0x1234_5678_9ABC_DEFF_EDCB_A987_6543_210;
-        let k_d = 0x2468_ACF1_3579_BDFF_DB97_530E_CA86_420;
-        let k_out = sub(k_d, k);
-        assert_eq!(k, k_out);
-    }
-}
diff --git a/src/test/run-pass/abi/proc_macro/auxiliary/test-macros.rs b/src/test/run-pass/abi/proc_macro/auxiliary/test-macros.rs
deleted file mode 100644
index 15fe3804f9b4f..0000000000000
--- a/src/test/run-pass/abi/proc_macro/auxiliary/test-macros.rs
+++ /dev/null
@@ -1,26 +0,0 @@
-// force-host
-// no-prefer-dynamic
-
-#![crate_type = "proc-macro"]
-
-extern crate proc_macro;
-
-use proc_macro::TokenStream;
-
-#[proc_macro_attribute]
-pub fn nop_attr(_attr: TokenStream, input: TokenStream) -> TokenStream {
-    assert!(_attr.to_string().is_empty());
-    input
-}
-
-#[proc_macro_attribute]
-pub fn no_output(_attr: TokenStream, _input: TokenStream) -> TokenStream {
-    assert!(_attr.to_string().is_empty());
-    assert!(!_input.to_string().is_empty());
-    "".parse().unwrap()
-}
-
-#[proc_macro]
-pub fn emit_input(input: TokenStream) -> TokenStream {
-    input
-}
diff --git a/src/test/run-pass/abi/proc_macro/macros-in-extern.rs b/src/test/run-pass/abi/proc_macro/macros-in-extern.rs
deleted file mode 100644
index 99e3f7d14fd16..0000000000000
--- a/src/test/run-pass/abi/proc_macro/macros-in-extern.rs
+++ /dev/null
@@ -1,24 +0,0 @@
-// aux-build:test-macros.rs
-// ignore-wasm32
-
-#![feature(macros_in_extern)]
-
-extern crate test_macros;
-
-use test_macros::{nop_attr, no_output, emit_input};
-
-fn main() {
-    assert_eq!(unsafe { rust_get_test_int() }, 1isize);
-    assert_eq!(unsafe { rust_dbg_extern_identity_u32(0xDEADBEEF) }, 0xDEADBEEF);
-}
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern {
-    #[no_output]
-    fn some_definitely_unknown_symbol_which_should_be_removed();
-
-    #[nop_attr]
-    fn rust_get_test_int() -> isize;
-
-    emit_input!(fn rust_dbg_extern_identity_u32(arg: u32) -> u32;);
-}
diff --git a/src/test/run-pass/abi/rfcs/rfc1717/library-override.rs b/src/test/run-pass/abi/rfcs/rfc1717/library-override.rs
deleted file mode 100644
index 014ccac31b7a5..0000000000000
--- a/src/test/run-pass/abi/rfcs/rfc1717/library-override.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-// run-pass
-// ignore-wasm32-bare no libc to test ffi with
-// compile-flags: -lstatic=wronglibrary:rust_test_helpers
-
-#[link(name = "wronglibrary", kind = "dylib")]
-extern "C" {
-    pub fn rust_dbg_extern_identity_u32(x: u32) -> u32;
-}
-
-fn main() {
-    unsafe {
-        rust_dbg_extern_identity_u32(42);
-    }
-}
diff --git a/src/test/run-pass/abi/segfault-no-out-of-stack.rs b/src/test/run-pass/abi/segfault-no-out-of-stack.rs
deleted file mode 100644
index e90efface687b..0000000000000
--- a/src/test/run-pass/abi/segfault-no-out-of-stack.rs
+++ /dev/null
@@ -1,48 +0,0 @@
-#![allow(unused_imports)]
-// ignore-cloudabi can't run commands
-// ignore-emscripten can't run commands
-// ignore-sgx no processes
-
-#![feature(rustc_private)]
-
-extern crate libc;
-
-use std::process::{Command, ExitStatus};
-use std::env;
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern {
-    fn rust_get_null_ptr() -> *mut ::libc::c_char;
-}
-
-#[cfg(unix)]
-fn check_status(status: std::process::ExitStatus)
-{
-    use libc;
-    use std::os::unix::process::ExitStatusExt;
-
-    assert!(status.signal() == Some(libc::SIGSEGV)
-            || status.signal() == Some(libc::SIGBUS));
-}
-
-#[cfg(not(unix))]
-fn check_status(status: std::process::ExitStatus)
-{
-    assert!(!status.success());
-}
-
-fn main() {
-    let args: Vec<String> = env::args().collect();
-    if args.len() > 1 && args[1] == "segfault" {
-        unsafe { *rust_get_null_ptr() = 1; }; // trigger a segfault
-    } else {
-        let segfault = Command::new(&args[0]).arg("segfault").output().unwrap();
-        let stderr = String::from_utf8_lossy(&segfault.stderr);
-        let stdout = String::from_utf8_lossy(&segfault.stdout);
-        println!("stdout: {}", stdout);
-        println!("stderr: {}", stderr);
-        println!("status: {}", segfault.status);
-        check_status(segfault.status);
-        assert!(!stderr.contains("has overflowed its stack"));
-    }
-}
diff --git a/src/test/run-pass/abi/stack-probes-lto.rs b/src/test/run-pass/abi/stack-probes-lto.rs
deleted file mode 100644
index 1274f032a3e29..0000000000000
--- a/src/test/run-pass/abi/stack-probes-lto.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-// ignore-arm
-// ignore-aarch64
-// ignore-mips
-// ignore-mips64
-// ignore-powerpc
-// ignore-s390x
-// ignore-sparc
-// ignore-sparc64
-// ignore-wasm
-// ignore-cloudabi no processes
-// ignore-emscripten no processes
-// ignore-sgx no processes
-// ignore-musl FIXME #31506
-// ignore-pretty
-// compile-flags: -C lto
-// no-prefer-dynamic
-
-include!("stack-probes.rs");
diff --git a/src/test/run-pass/abi/stack-probes.rs b/src/test/run-pass/abi/stack-probes.rs
deleted file mode 100644
index 773d0ace90ed9..0000000000000
--- a/src/test/run-pass/abi/stack-probes.rs
+++ /dev/null
@@ -1,67 +0,0 @@
-// ignore-arm
-// ignore-aarch64
-// ignore-mips
-// ignore-mips64
-// ignore-powerpc
-// ignore-s390x
-// ignore-sparc
-// ignore-sparc64
-// ignore-wasm
-// ignore-cloudabi no processes
-// ignore-emscripten no processes
-// ignore-sgx no processes
-// ignore-musl FIXME #31506
-
-use std::mem;
-use std::process::Command;
-use std::thread;
-use std::env;
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern {
-    #[link_name = "rust_dbg_extern_identity_u64"]
-    fn black_box(u: u64);
-}
-
-fn main() {
-    let args = env::args().skip(1).collect::<Vec<_>>();
-    if args.len() > 0 {
-        match &args[0][..] {
-            "main-thread" => recurse(&[]),
-            "child-thread" => thread::spawn(|| recurse(&[])).join().unwrap(),
-            _ => panic!(),
-        }
-        return
-    }
-
-    let me = env::current_exe().unwrap();
-
-    // The linux kernel has some different behavior for the main thread because
-    // the main thread's stack can typically grow. We can't always guarantee
-    // that we report stack overflow on the main thread, see #43052 for some
-    // details
-    if cfg!(not(target_os = "linux")) {
-        assert_overflow(Command::new(&me).arg("main-thread"));
-    }
-    assert_overflow(Command::new(&me).arg("child-thread"));
-}
-
-#[allow(unconditional_recursion)]
-fn recurse(array: &[u64]) {
-    unsafe { black_box(array.as_ptr() as u64); }
-    #[allow(deprecated)]
-    let local: [_; 1024] = unsafe { mem::uninitialized() };
-    recurse(&local);
-}
-
-fn assert_overflow(cmd: &mut Command) {
-    let output = cmd.output().unwrap();
-    assert!(!output.status.success());
-    let stdout = String::from_utf8_lossy(&output.stdout);
-    let stderr = String::from_utf8_lossy(&output.stderr);
-    println!("status: {}", output.status);
-    println!("stdout: {}", stdout);
-    println!("stderr: {}", stderr);
-    assert!(stdout.is_empty());
-    assert!(stderr.contains("has overflowed its stack\n"));
-}
diff --git a/src/test/run-pass/abi/statics/static-mut-foreign.rs b/src/test/run-pass/abi/statics/static-mut-foreign.rs
deleted file mode 100644
index 5d6fa416b9895..0000000000000
--- a/src/test/run-pass/abi/statics/static-mut-foreign.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-// run-pass
-// Constants (static variables) can be used to match in patterns, but mutable
-// statics cannot. This ensures that there's some form of error if this is
-// attempted.
-
-// ignore-wasm32-bare no libc to test ffi with
-
-#![feature(rustc_private)]
-
-extern crate libc;
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern {
-    static mut rust_dbg_static_mut: libc::c_int;
-    pub fn rust_dbg_static_mut_check_four();
-}
-
-unsafe fn static_bound(_: &'static libc::c_int) {}
-
-fn static_bound_set(a: &'static mut libc::c_int) {
-    *a = 3;
-}
-
-unsafe fn run() {
-    assert_eq!(rust_dbg_static_mut, 3);
-    rust_dbg_static_mut = 4;
-    assert_eq!(rust_dbg_static_mut, 4);
-    rust_dbg_static_mut_check_four();
-    rust_dbg_static_mut += 1;
-    assert_eq!(rust_dbg_static_mut, 5);
-    rust_dbg_static_mut *= 3;
-    assert_eq!(rust_dbg_static_mut, 15);
-    rust_dbg_static_mut = -3;
-    assert_eq!(rust_dbg_static_mut, -3);
-    static_bound(&rust_dbg_static_mut);
-    static_bound_set(&mut rust_dbg_static_mut);
-}
-
-pub fn main() {
-    unsafe { run() }
-}
diff --git a/src/test/run-pass/abi/structs-enums/struct-return.rs b/src/test/run-pass/abi/structs-enums/struct-return.rs
deleted file mode 100644
index 5930fc4acbbe3..0000000000000
--- a/src/test/run-pass/abi/structs-enums/struct-return.rs
+++ /dev/null
@@ -1,64 +0,0 @@
-// run-pass
-#![allow(dead_code)]
-// ignore-wasm32-bare no libc to test ffi with
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub struct Quad { a: u64, b: u64, c: u64, d: u64 }
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub struct Floats { a: f64, b: u8, c: f64 }
-
-mod rustrt {
-    use super::{Floats, Quad};
-
-    #[link(name = "rust_test_helpers", kind = "static")]
-    extern {
-        pub fn rust_dbg_abi_1(q: Quad) -> Quad;
-        pub fn rust_dbg_abi_2(f: Floats) -> Floats;
-    }
-}
-
-fn test1() {
-    unsafe {
-        let q = Quad { a: 0xaaaa_aaaa_aaaa_aaaa,
-                 b: 0xbbbb_bbbb_bbbb_bbbb,
-                 c: 0xcccc_cccc_cccc_cccc,
-                 d: 0xdddd_dddd_dddd_dddd };
-        let qq = rustrt::rust_dbg_abi_1(q);
-        println!("a: {:x}", qq.a as usize);
-        println!("b: {:x}", qq.b as usize);
-        println!("c: {:x}", qq.c as usize);
-        println!("d: {:x}", qq.d as usize);
-        assert_eq!(qq.a, q.c + 1);
-        assert_eq!(qq.b, q.d - 1);
-        assert_eq!(qq.c, q.a + 1);
-        assert_eq!(qq.d, q.b - 1);
-    }
-}
-
-#[cfg(target_pointer_width = "64")]
-fn test2() {
-    unsafe {
-        let f = Floats { a: 1.234567890e-15_f64,
-                 b: 0b_1010_1010,
-                 c: 1.0987654321e-15_f64 };
-        let ff = rustrt::rust_dbg_abi_2(f);
-        println!("a: {}", ff.a as f64);
-        println!("b: {}", ff.b as usize);
-        println!("c: {}", ff.c as f64);
-        assert_eq!(ff.a, f.c + 1.0f64);
-        assert_eq!(ff.b, 0xff);
-        assert_eq!(ff.c, f.a - 1.0f64);
-    }
-}
-
-#[cfg(target_pointer_width = "32")]
-fn test2() {
-}
-
-pub fn main() {
-    test1();
-    test2();
-}
diff --git a/src/test/run-pass/abi/union/union-c-interop.rs b/src/test/run-pass/abi/union/union-c-interop.rs
deleted file mode 100644
index 00f04d5b7ff3d..0000000000000
--- a/src/test/run-pass/abi/union/union-c-interop.rs
+++ /dev/null
@@ -1,37 +0,0 @@
-// run-pass
-#![allow(non_snake_case)]
-
-// ignore-wasm32-bare no libc to test ffi with
-
-#[derive(Clone, Copy)]
-#[repr(C)]
-struct LARGE_INTEGER_U {
-    LowPart: u32,
-    HighPart: u32,
-}
-
-#[derive(Clone, Copy)]
-#[repr(C)]
-union LARGE_INTEGER {
-  __unnamed__: LARGE_INTEGER_U,
-  u: LARGE_INTEGER_U,
-  QuadPart: u64,
-}
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern "C" {
-    fn increment_all_parts(_: LARGE_INTEGER) -> LARGE_INTEGER;
-}
-
-fn main() {
-    unsafe {
-        let mut li = LARGE_INTEGER { QuadPart: 0 };
-        let li_c = increment_all_parts(li);
-        li.__unnamed__.LowPart += 1;
-        li.__unnamed__.HighPart += 1;
-        li.u.LowPart += 1;
-        li.u.HighPart += 1;
-        li.QuadPart += 1;
-        assert_eq!(li.QuadPart, li_c.QuadPart);
-    }
-}
diff --git a/src/test/run-pass/abi/variadic-ffi.rs b/src/test/run-pass/abi/variadic-ffi.rs
deleted file mode 100644
index d6fbb1773b29f..0000000000000
--- a/src/test/run-pass/abi/variadic-ffi.rs
+++ /dev/null
@@ -1,83 +0,0 @@
-// ignore-wasm32-bare no libc to test ffi with
-#![feature(c_variadic)]
-
-use std::ffi::VaList;
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern {
-    fn rust_interesting_average(_: u64, ...) -> f64;
-
-    // FIXME: we need to disable this lint for `VaList`,
-    // since it contains a `MaybeUninit<i32>` on the asmjs target,
-    // and this type isn't FFI-safe. This is OK for now,
-    // since the type is layout-compatible with `i32`.
-    #[cfg_attr(target_arch = "asmjs", allow(improper_ctypes))]
-    fn rust_valist_interesting_average(_: u64, _: VaList) -> f64;
-}
-
-pub unsafe extern "C" fn test_valist_forward(n: u64, mut ap: ...) -> f64 {
-    rust_valist_interesting_average(n, ap.as_va_list())
-}
-
-pub unsafe extern "C" fn test_va_copy(_: u64, mut ap: ...) {
-    let mut ap2 = ap.clone();
-    assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 30);
-
-    // Advance one pair in the copy before checking
-    let mut ap2 = ap.clone();
-    let _ = ap2.arg::<u64>();
-    let _ = ap2.arg::<f64>();
-    assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 50);
-
-    // Advance one pair in the original
-    let _ = ap.arg::<u64>();
-    let _ = ap.arg::<f64>();
-
-    let mut ap2 = ap.clone();
-    assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 50);
-
-    let mut ap2 = ap.clone();
-    let _ = ap2.arg::<u64>();
-    let _ = ap2.arg::<f64>();
-    assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 70);
-}
-
-pub fn main() {
-    // Call without variadic arguments
-    unsafe {
-        assert!(rust_interesting_average(0).is_nan());
-    }
-
-    // Call with direct arguments
-    unsafe {
-        assert_eq!(rust_interesting_average(1, 10i64, 10.0f64) as i64, 20);
-    }
-
-    // Call with named arguments, variable number of them
-    let (x1, x2, x3, x4) = (10i64, 10.0f64, 20i64, 20.0f64);
-    unsafe {
-        assert_eq!(rust_interesting_average(2, x1, x2, x3, x4) as i64, 30);
-    }
-
-    // A function that takes a function pointer
-    unsafe fn call(fp: unsafe extern fn(u64, ...) -> f64) {
-        let (x1, x2, x3, x4) = (10i64, 10.0f64, 20i64, 20.0f64);
-        assert_eq!(fp(2, x1, x2, x3, x4) as i64, 30);
-    }
-
-    unsafe {
-        call(rust_interesting_average);
-
-        // Make a function pointer, pass indirectly
-        let x: unsafe extern fn(u64, ...) -> f64 = rust_interesting_average;
-        call(x);
-    }
-
-    unsafe {
-        assert_eq!(test_valist_forward(2, 10i64, 10f64, 20i64, 20f64) as i64, 30);
-    }
-
-    unsafe {
-        test_va_copy(4, 10i64, 10f64, 20i64, 20f64, 30i64, 30f64, 40i64, 40f64);
-    }
-}

From 26ee99e5d473e8743e3faa08c6cb89d3acb29104 Mon Sep 17 00:00:00 2001
From: Kevin Per <kevin.per@protonmail.com>
Date: Thu, 15 Aug 2019 19:26:51 +0200
Subject: [PATCH 17/35] Duplicate `test-macros.rs` to fix test #62593

---
 .../abi/proc-macro/auxiliary/test-macros.rs   | 112 ++++++++++++++++++
 1 file changed, 112 insertions(+)
 create mode 100644 src/test/ui/abi/proc-macro/auxiliary/test-macros.rs

diff --git a/src/test/ui/abi/proc-macro/auxiliary/test-macros.rs b/src/test/ui/abi/proc-macro/auxiliary/test-macros.rs
new file mode 100644
index 0000000000000..27efa44f98032
--- /dev/null
+++ b/src/test/ui/abi/proc-macro/auxiliary/test-macros.rs
@@ -0,0 +1,112 @@
+// force-host
+// no-prefer-dynamic
+
+// Proc macros commonly used by tests.
+// `panic`/`print` -> `panic_bang`/`print_bang` to avoid conflicts with standard macros.
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::TokenStream;
+
+// Macro that return empty token stream.
+
+#[proc_macro]
+pub fn empty(_: TokenStream) -> TokenStream {
+    TokenStream::new()
+}
+
+#[proc_macro_attribute]
+pub fn empty_attr(_: TokenStream, _: TokenStream) -> TokenStream {
+    TokenStream::new()
+}
+
+#[proc_macro_derive(Empty, attributes(empty_helper))]
+pub fn empty_derive(_: TokenStream) -> TokenStream {
+    TokenStream::new()
+}
+
+// Macro that panics.
+
+#[proc_macro]
+pub fn panic_bang(_: TokenStream) -> TokenStream {
+    panic!("panic-bang");
+}
+
+#[proc_macro_attribute]
+pub fn panic_attr(_: TokenStream, _: TokenStream) -> TokenStream {
+    panic!("panic-attr");
+}
+
+#[proc_macro_derive(Panic, attributes(panic_helper))]
+pub fn panic_derive(_: TokenStream) -> TokenStream {
+    panic!("panic-derive");
+}
+
+// Macros that return the input stream.
+
+#[proc_macro]
+pub fn identity(input: TokenStream) -> TokenStream {
+    input
+}
+
+#[proc_macro_attribute]
+pub fn identity_attr(_: TokenStream, input: TokenStream) -> TokenStream {
+    input
+}
+
+#[proc_macro_derive(Identity, attributes(identity_helper))]
+pub fn identity_derive(input: TokenStream) -> TokenStream {
+    input
+}
+
+// Macros that iterate and re-collect the input stream.
+
+#[proc_macro]
+pub fn recollect(input: TokenStream) -> TokenStream {
+    input.into_iter().collect()
+}
+
+#[proc_macro_attribute]
+pub fn recollect_attr(_: TokenStream, input: TokenStream) -> TokenStream {
+    input.into_iter().collect()
+}
+
+#[proc_macro_derive(Recollect, attributes(recollect_helper))]
+pub fn recollect_derive(input: TokenStream) -> TokenStream {
+    input.into_iter().collect()
+}
+
+// Macros that print their input in the original and re-collected forms (if they differ).
+
+fn print_helper(input: TokenStream, kind: &str) -> TokenStream {
+    let input_display = format!("{}", input);
+    let input_debug = format!("{:#?}", input);
+    let recollected = input.into_iter().collect();
+    let recollected_display = format!("{}", recollected);
+    let recollected_debug = format!("{:#?}", recollected);
+    println!("PRINT-{} INPUT (DISPLAY): {}", kind, input_display);
+    if recollected_display != input_display {
+        println!("PRINT-{} RE-COLLECTED (DISPLAY): {}", kind, recollected_display);
+    }
+    println!("PRINT-{} INPUT (DEBUG): {}", kind, input_debug);
+    if recollected_debug != input_debug {
+        println!("PRINT-{} RE-COLLECTED (DEBUG): {}", kind, recollected_debug);
+    }
+    recollected
+}
+
+#[proc_macro]
+pub fn print_bang(input: TokenStream) -> TokenStream {
+    print_helper(input, "BANG")
+}
+
+#[proc_macro_attribute]
+pub fn print_attr(_: TokenStream, input: TokenStream) -> TokenStream {
+    print_helper(input, "ATTR")
+}
+
+#[proc_macro_derive(Print, attributes(print_helper))]
+pub fn print_derive(input: TokenStream) -> TokenStream {
+    print_helper(input, "DERIVE")
+}

From dfcbe75900f2cb813754ef104526ebce568fd75b Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Sun, 11 Aug 2019 01:08:30 +0300
Subject: [PATCH 18/35] syntax_pos: Introduce a helper for checking whether a
 span comes from expansion

---
 src/librustc/lint/internal.rs               | 2 +-
 src/librustc_codegen_ssa/mir/mod.rs         | 4 ++--
 src/librustc_lint/builtin.rs                | 8 ++++----
 src/librustc_lint/unused.rs                 | 2 +-
 src/librustc_resolve/lib.rs                 | 4 ++--
 src/librustc_save_analysis/lib.rs           | 2 +-
 src/librustc_typeck/check/demand.rs         | 6 +++---
 src/librustc_typeck/check/method/suggest.rs | 4 ++--
 src/libsyntax/parse/parser.rs               | 2 +-
 src/libsyntax_pos/hygiene.rs                | 2 +-
 src/libsyntax_pos/lib.rs                    | 6 ++++++
 src/libsyntax_pos/symbol.rs                 | 3 +--
 12 files changed, 25 insertions(+), 20 deletions(-)

diff --git a/src/librustc/lint/internal.rs b/src/librustc/lint/internal.rs
index dea1cc6601b04..d9ad34a5297f7 100644
--- a/src/librustc/lint/internal.rs
+++ b/src/librustc/lint/internal.rs
@@ -108,7 +108,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TyTyKind {
                             .help("try using `Ty` instead")
                             .emit();
                         } else {
-                            if ty.span.ctxt().outer_expn_info().is_some() {
+                            if ty.span.from_expansion() {
                                 return;
                             }
                             if let Some(t) = is_ty_or_ty_ctxt(cx, ty) {
diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs
index e7517d6999195..32bcdebc1c467 100644
--- a/src/librustc_codegen_ssa/mir/mod.rs
+++ b/src/librustc_codegen_ssa/mir/mod.rs
@@ -8,7 +8,7 @@ use crate::base;
 use crate::debuginfo::{self, VariableAccess, VariableKind, FunctionDebugContext};
 use crate::traits::*;
 
-use syntax_pos::{DUMMY_SP, NO_EXPANSION, BytePos, Span};
+use syntax_pos::{DUMMY_SP, BytePos, Span};
 use syntax::symbol::kw;
 
 use std::iter;
@@ -120,7 +120,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         // In order to have a good line stepping behavior in debugger, we overwrite debug
         // locations of macro expansions with that of the outermost expansion site
         // (unless the crate is being compiled with `-Z debug-macros`).
-        if source_info.span.ctxt() == NO_EXPANSION ||
+        if !source_info.span.from_expansion() ||
            self.cx.sess().opts.debugging_opts.debug_macros {
             let scope = self.scope_metadata_for_loc(source_info.scope, source_info.span.lo());
             (scope, source_info.span)
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 47b4e7c948750..82160080a44d4 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -42,7 +42,7 @@ use syntax::source_map::Spanned;
 use syntax::edition::Edition;
 use syntax::feature_gate::{self, AttributeGate, AttributeType};
 use syntax::feature_gate::{Stability, deprecated_attributes};
-use syntax_pos::{BytePos, Span, SyntaxContext};
+use syntax_pos::{BytePos, Span};
 use syntax::symbol::{Symbol, kw, sym};
 use syntax::errors::{Applicability, DiagnosticBuilder};
 use syntax::print::pprust::expr_to_string;
@@ -78,7 +78,7 @@ impl EarlyLintPass for WhileTrue {
         if let ast::ExprKind::While(cond, ..) = &e.node {
             if let ast::ExprKind::Lit(ref lit) = pierce_parens(cond).node {
                 if let ast::LitKind::Bool(true) = lit.node {
-                    if lit.span.ctxt() == SyntaxContext::empty() {
+                    if !lit.span.from_expansion() {
                         let msg = "denote infinite loops with `loop { ... }`";
                         let condition_span = cx.sess.source_map().def_span(e.span);
                         cx.struct_span_lint(WHILE_TRUE, condition_span, msg)
@@ -167,7 +167,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonShorthandFieldPatterns {
                 if fieldpat.is_shorthand {
                     continue;
                 }
-                if fieldpat.span.ctxt().outer_expn_info().is_some() {
+                if fieldpat.span.from_expansion() {
                     // Don't lint if this is a macro expansion: macro authors
                     // shouldn't have to worry about this kind of style issue
                     // (Issue #49588)
@@ -1012,7 +1012,7 @@ impl UnreachablePub {
         let mut applicability = Applicability::MachineApplicable;
         match vis.node {
             hir::VisibilityKind::Public if !cx.access_levels.is_reachable(id) => {
-                if span.ctxt().outer_expn_info().is_some() {
+                if span.from_expansion() {
                     applicability = Applicability::MaybeIncorrect;
                 }
                 let def_span = cx.tcx.sess.source_map().def_span(span);
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index 6a3dfdbe31684..9cad8f58d41da 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -518,7 +518,7 @@ impl EarlyLintPass for UnusedParens {
                 // when a parenthesized token tree matched in one macro expansion is matched as
                 // an expression in another and used as a fn/method argument (Issue #47775)
                 if e.span.ctxt().outer_expn_info()
-                    .map_or(false, |info| info.call_site.ctxt().outer_expn_info().is_some()) {
+                    .map_or(false, |info| info.call_site.from_expansion()) {
                         return;
                 }
                 let msg = format!("{} argument", call_kind);
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 8a4a60c16b0fe..f0916c2ff3e26 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -274,7 +274,7 @@ impl<'tcx> Visitor<'tcx> for UsePlacementFinder {
                 ItemKind::Use(..) => {
                     // don't suggest placing a use before the prelude
                     // import or other generated ones
-                    if item.span.ctxt().outer_expn_info().is_none() {
+                    if !item.span.from_expansion() {
                         self.span = Some(item.span.shrink_to_lo());
                         self.found_use = true;
                         return;
@@ -284,7 +284,7 @@ impl<'tcx> Visitor<'tcx> for UsePlacementFinder {
                 ItemKind::ExternCrate(_) => {}
                 // but place them before the first other item
                 _ => if self.span.map_or(true, |span| item.span < span ) {
-                    if item.span.ctxt().outer_expn_info().is_none() {
+                    if !item.span.from_expansion() {
                         // don't insert between attributes and an item
                         if item.attrs.is_empty() {
                             self.span = Some(item.span.shrink_to_lo());
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index 9da6cd800570e..0bbbbb8249c20 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -1156,7 +1156,7 @@ fn escape(s: String) -> String {
 // Helper function to determine if a span came from a
 // macro expansion or syntax extension.
 fn generated_code(span: Span) -> bool {
-    span.ctxt() != NO_EXPANSION || span.is_dummy()
+    span.from_expansion() || span.is_dummy()
 }
 
 // DefId::index is a newtype and so the JSON serialisation is ugly. Therefore
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index ed25601208ad1..c72966edc5ae8 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -347,9 +347,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             sp,
         );
 
-        // Check the `expn_info()` to see if this is a macro; if so, it's hard to
-        // extract the text and make a good suggestion, so don't bother.
-        let is_macro = sp.ctxt().outer_expn_info().is_some();
+        // If the span is from a macro, then it's hard to extract the text
+        // and make a good suggestion, so don't bother.
+        let is_macro = sp.from_expansion();
 
         match (&expr.node, &expected.sty, &checked_ty.sty) {
             (_, &ty::Ref(_, exp, _), &ty::Ref(_, check, _)) => match (&exp.sty, &check.sty) {
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 4a5eba1df8836..53024d97c3b13 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -985,7 +985,7 @@ impl hir::intravisit::Visitor<'tcx> for UsePlacementFinder<'tcx> {
                 hir::ItemKind::Use(..) => {
                     // Don't suggest placing a `use` before the prelude
                     // import or other generated ones.
-                    if item.span.ctxt().outer_expn_info().is_none() {
+                    if !item.span.from_expansion() {
                         self.span = Some(item.span.shrink_to_lo());
                         self.found_use = true;
                         return;
@@ -995,7 +995,7 @@ impl hir::intravisit::Visitor<'tcx> for UsePlacementFinder<'tcx> {
                 hir::ItemKind::ExternCrate(_) => {}
                 // ...but do place them before the first other item.
                 _ => if self.span.map_or(true, |span| item.span < span ) {
-                    if item.span.ctxt().outer_expn_info().is_none() {
+                    if !item.span.from_expansion() {
                         // Don't insert between attributes and an item.
                         if item.attrs.is_empty() {
                             self.span = Some(item.span.shrink_to_lo());
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 2286e74e63304..3b0af88f6510e 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -1101,7 +1101,7 @@ impl<'a> Parser<'a> {
 
     crate fn process_potential_macro_variable(&mut self) {
         self.token = match self.token.kind {
-            token::Dollar if self.token.span.ctxt() != SyntaxContext::empty() &&
+            token::Dollar if self.token.span.from_expansion() &&
                              self.look_ahead(1, |t| t.is_ident()) => {
                 self.bump();
                 let name = match self.token.kind {
diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs
index f91a22915445c..4132b99cf4160 100644
--- a/src/libsyntax_pos/hygiene.rs
+++ b/src/libsyntax_pos/hygiene.rs
@@ -255,7 +255,7 @@ impl HygieneData {
     }
 
     fn walk_chain(&self, mut span: Span, to: SyntaxContext) -> Span {
-        while span.ctxt() != crate::NO_EXPANSION && span.ctxt() != to {
+        while span.from_expansion() && span.ctxt() != to {
             if let Some(info) = self.expn_info(self.outer_expn(span.ctxt())) {
                 span = info.call_site;
             } else {
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index 02a7433d9469d..793710b453f24 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -288,6 +288,12 @@ impl Span {
         span.lo.0 == 0 && span.hi.0 == 0
     }
 
+    /// Returns `true` if this span comes from a macro or desugaring.
+    #[inline]
+    pub fn from_expansion(self) -> bool {
+        self.ctxt() != SyntaxContext::empty()
+    }
+
     /// Returns a new span representing an empty span at the beginning of this span
     #[inline]
     pub fn shrink_to_lo(self) -> Span {
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index 2d9556233d15f..6f5a458a874e1 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -14,7 +14,6 @@ use std::fmt;
 use std::hash::{Hash, Hasher};
 use std::str;
 
-use crate::hygiene::SyntaxContext;
 use crate::{Span, DUMMY_SP, GLOBALS};
 
 #[cfg(test)]
@@ -851,7 +850,7 @@ impl fmt::Display for Ident {
 
 impl Encodable for Ident {
     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        if self.span.ctxt().modern() == SyntaxContext::empty() {
+        if !self.span.modern().from_expansion() {
             s.emit_str(&self.as_str())
         } else { // FIXME(jseyfried): intercrate hygiene
             let mut string = "#".to_owned();

From 67d6ce42063732d7c7b12d94f872dcafb5efb607 Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Sun, 11 Aug 2019 01:44:55 +0300
Subject: [PATCH 19/35] syntax_pos: `NO_EXPANSION`/`SyntaxContext::empty()` ->
 `SyntaxContext::root()`

For consistency with `ExpnId::root`.

Also introduce a helper `Span::with_root_ctxt` for creating spans with `SyntaxContext::root()` context
---
 src/librustc/ich/hcx.rs                    |  2 +-
 src/librustc/ty/query/on_disk_cache.rs     |  4 ++--
 src/librustc_errors/lib.rs                 |  5 ++---
 src/librustc_metadata/cstore_impl.rs       |  4 ++--
 src/librustc_metadata/decoder.rs           |  4 ++--
 src/librustc_resolve/lib.rs                |  2 +-
 src/libsyntax/ext/base.rs                  |  2 +-
 src/libsyntax/ext/expand.rs                |  2 +-
 src/libsyntax/ext/proc_macro_server.rs     |  2 +-
 src/libsyntax/parse/lexer/mod.rs           |  4 ++--
 src/libsyntax/parse/lexer/tests.rs         |  6 +++---
 src/libsyntax/parse/lexer/unicode_chars.rs |  7 +++----
 src/libsyntax/parse/tests.rs               |  4 ++--
 src/libsyntax/source_map/tests.rs          | 11 +++++------
 src/libsyntax/tests.rs                     |  4 ++--
 src/libsyntax/tokenstream/tests.rs         |  4 ++--
 src/libsyntax_ext/global_allocator.rs      |  2 +-
 src/libsyntax_ext/test.rs                  |  4 ++--
 src/libsyntax_pos/hygiene.rs               | 12 ++++++------
 src/libsyntax_pos/lib.rs                   | 21 ++++++++++++---------
 20 files changed, 53 insertions(+), 53 deletions(-)

diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs
index ae7d82c2020ac..39f6b0d434440 100644
--- a/src/librustc/ich/hcx.rs
+++ b/src/librustc/ich/hcx.rs
@@ -350,7 +350,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for Span {
         let line_col_len = col | line | len;
         std_hash::Hash::hash(&line_col_len, hasher);
 
-        if span.ctxt == SyntaxContext::empty() {
+        if span.ctxt == SyntaxContext::root() {
             TAG_NO_EXPANSION.hash_stable(hcx, hasher);
         } else {
             TAG_EXPANSION.hash_stable(hcx, hasher);
diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs
index 00871a1cbf2a9..1c5baa638c2b1 100644
--- a/src/librustc/ty/query/on_disk_cache.rs
+++ b/src/librustc/ty/query/on_disk_cache.rs
@@ -592,7 +592,7 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx> {
         // `SyntaxContextData::prev_ctxt` or `SyntaxContextData::opaque`. These things
         // don't seem to be used after HIR lowering, so everything should be fine
         // as long as incremental compilation does not kick in before that.
-        let location = || Span::new(lo, hi, SyntaxContext::empty());
+        let location = || Span::with_root_ctxt(lo, hi);
         let recover_from_expn_info = |this: &Self, expn_info, pos| {
             let span = location().fresh_expansion(ExpnId::root(), expn_info);
             this.synthetic_expansion_infos.borrow_mut().insert(pos, span.ctxt());
@@ -816,7 +816,7 @@ where
         col_lo.encode(self)?;
         len.encode(self)?;
 
-        if span_data.ctxt == SyntaxContext::empty() {
+        if span_data.ctxt == SyntaxContext::root() {
             TAG_NO_EXPANSION_INFO.encode(self)
         } else {
             let (expn_id, expn_info) = span_data.ctxt.outer_expn_with_info();
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index f3e524152ffae..4018a667bf264 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -43,8 +43,7 @@ use syntax_pos::{BytePos,
                  SourceFile,
                  FileName,
                  MultiSpan,
-                 Span,
-                 NO_EXPANSION};
+                 Span};
 
 /// Indicates the confidence in the correctness of a suggestion.
 ///
@@ -189,7 +188,7 @@ impl CodeSuggestion {
             // Find the bounding span.
             let lo = substitution.parts.iter().map(|part| part.span.lo()).min().unwrap();
             let hi = substitution.parts.iter().map(|part| part.span.hi()).min().unwrap();
-            let bounding_span = Span::new(lo, hi, NO_EXPANSION);
+            let bounding_span = Span::with_root_ctxt(lo, hi);
             let lines = cm.span_to_lines(bounding_span).unwrap();
             assert!(!lines.lines.is_empty());
 
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index ee1175e798d80..b46758abb5f2c 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -35,7 +35,7 @@ use syntax::ext::proc_macro::BangProcMacro;
 use syntax::parse::source_file_to_stream;
 use syntax::parse::parser::emit_unclosed_delims;
 use syntax::symbol::{Symbol, sym};
-use syntax_pos::{Span, NO_EXPANSION, FileName};
+use syntax_pos::{Span, FileName};
 use rustc_data_structures::bit_set::BitSet;
 
 macro_rules! provide {
@@ -443,7 +443,7 @@ impl cstore::CStore {
         let source_name = FileName::Macros(macro_full_name);
 
         let source_file = sess.parse_sess.source_map().new_source_file(source_name, def.body);
-        let local_span = Span::new(source_file.start_pos, source_file.end_pos, NO_EXPANSION);
+        let local_span = Span::with_root_ctxt(source_file.start_pos, source_file.end_pos);
         let (body, mut errors) = source_file_to_stream(&sess.parse_sess, source_file, None);
         emit_unclosed_delims(&mut errors, &sess.diagnostic());
 
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 935187dd0667b..3de9bf4da11ea 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -32,7 +32,7 @@ use syntax::source_map;
 use syntax::symbol::{Symbol, sym};
 use syntax::ext::base::{MacroKind, SyntaxExtension};
 use syntax::ext::hygiene::ExpnId;
-use syntax_pos::{self, Span, BytePos, Pos, DUMMY_SP, NO_EXPANSION};
+use syntax_pos::{self, Span, BytePos, Pos, DUMMY_SP};
 use log::debug;
 
 pub struct DecodeContext<'a, 'tcx> {
@@ -344,7 +344,7 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
         let hi = (hi + source_file.translated_source_file.start_pos)
                  - source_file.original_start_pos;
 
-        Ok(Span::new(lo, hi, NO_EXPANSION))
+        Ok(Span::with_root_ctxt(lo, hi))
     }
 }
 
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index f0916c2ff3e26..8b2e371f0f612 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -1430,7 +1430,7 @@ impl<'a> Resolver<'a> {
         }
         let (general_span, modern_span) = if ident.name == kw::SelfUpper {
             // FIXME(jseyfried) improve `Self` hygiene
-            let empty_span = ident.span.with_ctxt(SyntaxContext::empty());
+            let empty_span = ident.span.with_ctxt(SyntaxContext::root());
             (empty_span, empty_span)
         } else if ns == TypeNS {
             let modern_span = ident.span.modern();
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index edeca046c7b8f..d9fd31db4dd60 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -762,7 +762,7 @@ impl<'a> ExtCtxt<'a> {
         }
     }
     pub fn backtrace(&self) -> SyntaxContext {
-        SyntaxContext::empty().apply_mark(self.current_expansion.id)
+        SyntaxContext::root().apply_mark(self.current_expansion.id)
     }
 
     /// Returns span for the macro which originally caused the current expansion to happen.
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 97983944931ba..aa409199afd6d 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -759,7 +759,7 @@ impl<'a> Parser<'a> {
             let msg = format!("macro expansion ignores token `{}` and any following",
                               self.this_token_to_string());
             // Avoid emitting backtrace info twice.
-            let def_site_span = self.token.span.with_ctxt(SyntaxContext::empty());
+            let def_site_span = self.token.span.with_ctxt(SyntaxContext::root());
             let mut err = self.diagnostic().struct_span_err(def_site_span, &msg);
             err.span_label(span, "caused by the macro expansion here");
             let msg = format!(
diff --git a/src/libsyntax/ext/proc_macro_server.rs b/src/libsyntax/ext/proc_macro_server.rs
index 36621ce777510..fd93910004efe 100644
--- a/src/libsyntax/ext/proc_macro_server.rs
+++ b/src/libsyntax/ext/proc_macro_server.rs
@@ -365,7 +365,7 @@ impl<'a> Rustc<'a> {
         let location = cx.current_expansion.id.expn_info().unwrap().call_site;
         let to_span = |transparency| {
             location.with_ctxt(
-                SyntaxContext::empty()
+                SyntaxContext::root()
                     .apply_mark_with_transparency(cx.current_expansion.id, transparency),
             )
         };
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index e86d4c7fde683..17629d392cd3d 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -4,7 +4,7 @@ use crate::symbol::{sym, Symbol};
 use crate::parse::unescape_error_reporting::{emit_unescape_error, push_escaped_char};
 
 use errors::{FatalError, DiagnosticBuilder};
-use syntax_pos::{BytePos, Pos, Span, NO_EXPANSION};
+use syntax_pos::{BytePos, Pos, Span};
 use rustc_lexer::Base;
 use rustc_lexer::unescape;
 
@@ -84,7 +84,7 @@ impl<'a> StringReader<'a> {
 
 
     fn mk_sp(&self, lo: BytePos, hi: BytePos) -> Span {
-        self.override_span.unwrap_or_else(|| Span::new(lo, hi, NO_EXPANSION))
+        self.override_span.unwrap_or_else(|| Span::with_root_ctxt(lo, hi))
     }
 
     /// Returns the next token, including trivia like whitespace or comments.
diff --git a/src/libsyntax/parse/lexer/tests.rs b/src/libsyntax/parse/lexer/tests.rs
index fc47e4f0b185a..1e4d9048b41b8 100644
--- a/src/libsyntax/parse/lexer/tests.rs
+++ b/src/libsyntax/parse/lexer/tests.rs
@@ -9,7 +9,7 @@ use crate::diagnostics::plugin::ErrorMap;
 use crate::with_default_globals;
 use std::io;
 use std::path::PathBuf;
-use syntax_pos::{BytePos, Span, NO_EXPANSION, edition::Edition};
+use syntax_pos::{BytePos, Span, edition::Edition};
 use rustc_data_structures::fx::{FxHashSet, FxHashMap};
 use rustc_data_structures::sync::{Lock, Once};
 
@@ -61,7 +61,7 @@ fn t1() {
         let tok1 = string_reader.next_token();
         let tok2 = Token::new(
             mk_ident("fn"),
-            Span::new(BytePos(21), BytePos(23), NO_EXPANSION),
+            Span::with_root_ctxt(BytePos(21), BytePos(23)),
         );
         assert_eq!(tok1.kind, tok2.kind);
         assert_eq!(tok1.span, tok2.span);
@@ -71,7 +71,7 @@ fn t1() {
         assert_eq!(string_reader.pos.clone(), BytePos(28));
         let tok4 = Token::new(
             mk_ident("main"),
-            Span::new(BytePos(24), BytePos(28), NO_EXPANSION),
+            Span::with_root_ctxt(BytePos(24), BytePos(28)),
         );
         assert_eq!(tok3.kind, tok4.kind);
         assert_eq!(tok3.span, tok4.span);
diff --git a/src/libsyntax/parse/lexer/unicode_chars.rs b/src/libsyntax/parse/lexer/unicode_chars.rs
index eaa736c6a3517..525b4215affb1 100644
--- a/src/libsyntax/parse/lexer/unicode_chars.rs
+++ b/src/libsyntax/parse/lexer/unicode_chars.rs
@@ -3,7 +3,7 @@
 
 use super::StringReader;
 use errors::{Applicability, DiagnosticBuilder};
-use syntax_pos::{BytePos, Pos, Span, NO_EXPANSION, symbol::kw};
+use syntax_pos::{BytePos, Pos, Span, symbol::kw};
 use crate::parse::token;
 
 #[rustfmt::skip] // for line breaks
@@ -343,7 +343,7 @@ crate fn check_for_substitution<'a>(
         None => return None,
     };
 
-    let span = Span::new(pos, pos + Pos::from_usize(ch.len_utf8()), NO_EXPANSION);
+    let span = Span::with_root_ctxt(pos, pos + Pos::from_usize(ch.len_utf8()));
 
     let (ascii_name, token) = match ASCII_ARRAY.iter().find(|&&(c, _, _)| c == ascii_char) {
         Some((_ascii_char, ascii_name, token)) => (ascii_name, token),
@@ -362,10 +362,9 @@ crate fn check_for_substitution<'a>(
             ascii_char, ascii_name
         );
         err.span_suggestion(
-            Span::new(
+            Span::with_root_ctxt(
                 pos,
                 pos + Pos::from_usize('“'.len_utf8() + s.len() + '”'.len_utf8()),
-                NO_EXPANSION,
             ),
             &msg,
             format!("\"{}\"", s),
diff --git a/src/libsyntax/parse/tests.rs b/src/libsyntax/parse/tests.rs
index 9edc83a359414..6a789ef99d672 100644
--- a/src/libsyntax/parse/tests.rs
+++ b/src/libsyntax/parse/tests.rs
@@ -12,7 +12,7 @@ use crate::symbol::{kw, sym};
 use crate::tests::{matches_codepattern, string_to_stream, with_error_checking_parse};
 use crate::tokenstream::{DelimSpan, TokenTree, TokenStream};
 use crate::with_default_globals;
-use syntax_pos::{Span, BytePos, Pos, NO_EXPANSION};
+use syntax_pos::{Span, BytePos, Pos};
 
 use std::path::PathBuf;
 
@@ -27,7 +27,7 @@ fn parse_item_from_source_str(name: FileName, source: String, sess: &ParseSess)
 
 // produce a syntax_pos::span
 fn sp(a: u32, b: u32) -> Span {
-    Span::new(BytePos(a), BytePos(b), NO_EXPANSION)
+    Span::with_root_ctxt(BytePos(a), BytePos(b))
 }
 
 /// Parse a string, return an expr
diff --git a/src/libsyntax/source_map/tests.rs b/src/libsyntax/source_map/tests.rs
index 427e86b56e12b..c7b8332c53ef7 100644
--- a/src/libsyntax/source_map/tests.rs
+++ b/src/libsyntax/source_map/tests.rs
@@ -91,7 +91,7 @@ fn t6() {
 fn t7() {
     // Test span_to_lines for a span ending at the end of source_file
     let sm = init_source_map();
-    let span = Span::new(BytePos(12), BytePos(23), NO_EXPANSION);
+    let span = Span::with_root_ctxt(BytePos(12), BytePos(23));
     let file_lines = sm.span_to_lines(span).unwrap();
 
     assert_eq!(file_lines.file.name, PathBuf::from("blork.rs").into());
@@ -107,7 +107,7 @@ fn span_from_selection(input: &str, selection: &str) -> Span {
     assert_eq!(input.len(), selection.len());
     let left_index = selection.find('~').unwrap() as u32;
     let right_index = selection.rfind('~').map(|x|x as u32).unwrap_or(left_index);
-    Span::new(BytePos(left_index), BytePos(right_index + 1), NO_EXPANSION)
+    Span::with_root_ctxt(BytePos(left_index), BytePos(right_index + 1))
 }
 
 /// Tests span_to_snippet and span_to_lines for a span converting 3
@@ -137,7 +137,7 @@ fn span_to_snippet_and_lines_spanning_multiple_lines() {
 fn t8() {
     // Test span_to_snippet for a span ending at the end of source_file
     let sm = init_source_map();
-    let span = Span::new(BytePos(12), BytePos(23), NO_EXPANSION);
+    let span = Span::with_root_ctxt(BytePos(12), BytePos(23));
     let snippet = sm.span_to_snippet(span);
 
     assert_eq!(snippet, Ok("second line".to_string()));
@@ -147,7 +147,7 @@ fn t8() {
 fn t9() {
     // Test span_to_str for a span ending at the end of source_file
     let sm = init_source_map();
-    let span = Span::new(BytePos(12), BytePos(23), NO_EXPANSION);
+    let span = Span::with_root_ctxt(BytePos(12), BytePos(23));
     let sstr =  sm.span_to_string(span);
 
     assert_eq!(sstr, "blork.rs:2:1: 2:12");
@@ -198,10 +198,9 @@ impl SourceMapExtension for SourceMap {
             let lo = hi + offset;
             hi = lo + substring.len();
             if i == n {
-                let span = Span::new(
+                let span = Span::with_root_ctxt(
                     BytePos(lo as u32 + file.start_pos.0),
                     BytePos(hi as u32 + file.start_pos.0),
-                    NO_EXPANSION,
                 );
                 assert_eq!(&self.span_to_snippet(span).unwrap()[..],
                         substring);
diff --git a/src/libsyntax/tests.rs b/src/libsyntax/tests.rs
index cff034fdeb1e3..4c0e1e3704dff 100644
--- a/src/libsyntax/tests.rs
+++ b/src/libsyntax/tests.rs
@@ -9,7 +9,7 @@ use crate::with_default_globals;
 use errors::emitter::EmitterWriter;
 use errors::Handler;
 use rustc_data_structures::sync::Lrc;
-use syntax_pos::{BytePos, NO_EXPANSION, Span, MultiSpan};
+use syntax_pos::{BytePos, Span, MultiSpan};
 
 use std::io;
 use std::io::prelude::*;
@@ -169,7 +169,7 @@ fn make_span(file_text: &str, start: &Position, end: &Position) -> Span {
     let start = make_pos(file_text, start);
     let end = make_pos(file_text, end) + end.string.len(); // just after matching thing ends
     assert!(start <= end);
-    Span::new(BytePos(start as u32), BytePos(end as u32), NO_EXPANSION)
+    Span::with_root_ctxt(BytePos(start as u32), BytePos(end as u32))
 }
 
 fn make_pos(file_text: &str, pos: &Position) -> usize {
diff --git a/src/libsyntax/tokenstream/tests.rs b/src/libsyntax/tokenstream/tests.rs
index 72e22a49876e8..5017e5f5424c1 100644
--- a/src/libsyntax/tokenstream/tests.rs
+++ b/src/libsyntax/tokenstream/tests.rs
@@ -3,14 +3,14 @@ use super::*;
 use crate::ast::Name;
 use crate::with_default_globals;
 use crate::tests::string_to_stream;
-use syntax_pos::{Span, BytePos, NO_EXPANSION};
+use syntax_pos::{Span, BytePos};
 
 fn string_to_ts(string: &str) -> TokenStream {
     string_to_stream(string.to_owned())
 }
 
 fn sp(a: u32, b: u32) -> Span {
-    Span::new(BytePos(a), BytePos(b), NO_EXPANSION)
+    Span::with_root_ctxt(BytePos(a), BytePos(b))
 }
 
 #[test]
diff --git a/src/libsyntax_ext/global_allocator.rs b/src/libsyntax_ext/global_allocator.rs
index f788b51380433..b1f6f55732a93 100644
--- a/src/libsyntax_ext/global_allocator.rs
+++ b/src/libsyntax_ext/global_allocator.rs
@@ -29,7 +29,7 @@ pub fn expand(
     };
 
     // Generate a bunch of new items using the AllocFnFactory
-    let span = item.span.with_ctxt(SyntaxContext::empty().apply_mark(ecx.current_expansion.id));
+    let span = item.span.with_ctxt(SyntaxContext::root().apply_mark(ecx.current_expansion.id));
     let f = AllocFnFactory {
         span,
         kind: AllocatorKind::Global,
diff --git a/src/libsyntax_ext/test.rs b/src/libsyntax_ext/test.rs
index 993ef25752757..08582e714ccb2 100644
--- a/src/libsyntax_ext/test.rs
+++ b/src/libsyntax_ext/test.rs
@@ -29,7 +29,7 @@ pub fn expand_test_case(
 
     if !ecx.ecfg.should_test { return vec![]; }
 
-    let sp = attr_sp.with_ctxt(SyntaxContext::empty().apply_mark(ecx.current_expansion.id));
+    let sp = attr_sp.with_ctxt(SyntaxContext::root().apply_mark(ecx.current_expansion.id));
     let mut item = anno_item.expect_item();
     item = item.map(|mut item| {
         item.vis = respan(item.vis.span, ast::VisibilityKind::Public);
@@ -93,7 +93,7 @@ pub fn expand_test_or_bench(
         return vec![Annotatable::Item(item)];
     }
 
-    let ctxt = SyntaxContext::empty().apply_mark(cx.current_expansion.id);
+    let ctxt = SyntaxContext::root().apply_mark(cx.current_expansion.id);
     let (sp, attr_sp) = (item.span.with_ctxt(ctxt), attr_sp.with_ctxt(ctxt));
 
     // Gensym "test" so we can extern crate without conflicting with any local names
diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs
index 4132b99cf4160..c832e058cdf24 100644
--- a/src/libsyntax_pos/hygiene.rs
+++ b/src/libsyntax_pos/hygiene.rs
@@ -246,7 +246,7 @@ impl HygieneData {
 
     fn marks(&self, mut ctxt: SyntaxContext) -> Vec<(ExpnId, Transparency)> {
         let mut marks = Vec::new();
-        while ctxt != SyntaxContext::empty() {
+        while ctxt != SyntaxContext::root() {
             marks.push((self.outer_expn(ctxt), self.outer_transparency(ctxt)));
             ctxt = self.parent_ctxt(ctxt);
         }
@@ -286,14 +286,14 @@ impl HygieneData {
         }
 
         let call_site_ctxt =
-            self.expn_info(expn_id).map_or(SyntaxContext::empty(), |info| info.call_site.ctxt());
+            self.expn_info(expn_id).map_or(SyntaxContext::root(), |info| info.call_site.ctxt());
         let mut call_site_ctxt = if transparency == Transparency::SemiTransparent {
             self.modern(call_site_ctxt)
         } else {
             self.modern_and_legacy(call_site_ctxt)
         };
 
-        if call_site_ctxt == SyntaxContext::empty() {
+        if call_site_ctxt == SyntaxContext::root() {
             return self.apply_mark_internal(ctxt, expn_id, transparency);
         }
 
@@ -400,7 +400,7 @@ pub fn update_dollar_crate_names(mut get_name: impl FnMut(SyntaxContext) -> Symb
 
 impl SyntaxContext {
     #[inline]
-    pub const fn empty() -> Self {
+    pub const fn root() -> Self {
         SyntaxContext(0)
     }
 
@@ -615,7 +615,7 @@ impl Span {
     pub fn fresh_expansion(self, parent: ExpnId, expn_info: ExpnInfo) -> Span {
         HygieneData::with(|data| {
             let expn_id = data.fresh_expn(parent, Some(expn_info));
-            self.with_ctxt(data.apply_mark(SyntaxContext::empty(), expn_id))
+            self.with_ctxt(data.apply_mark(SyntaxContext::root(), expn_id))
         })
     }
 }
@@ -775,6 +775,6 @@ impl Encodable for SyntaxContext {
 
 impl Decodable for SyntaxContext {
     fn decode<D: Decoder>(_: &mut D) -> Result<SyntaxContext, D::Error> {
-        Ok(SyntaxContext::empty()) // FIXME(jseyfried) intercrate hygiene
+        Ok(SyntaxContext::root()) // FIXME(jseyfried) intercrate hygiene
     }
 }
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index 793710b453f24..7c8539198b96e 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -291,7 +291,12 @@ impl Span {
     /// Returns `true` if this span comes from a macro or desugaring.
     #[inline]
     pub fn from_expansion(self) -> bool {
-        self.ctxt() != SyntaxContext::empty()
+        self.ctxt() != SyntaxContext::root()
+    }
+
+    #[inline]
+    pub fn with_root_ctxt(lo: BytePos, hi: BytePos) -> Span {
+        Span::new(lo, hi, SyntaxContext::root())
     }
 
     /// Returns a new span representing an empty span at the beginning of this span
@@ -474,9 +479,9 @@ impl Span {
         // Return the macro span on its own to avoid weird diagnostic output. It is preferable to
         // have an incomplete span than a completely nonsensical one.
         if span_data.ctxt != end_data.ctxt {
-            if span_data.ctxt == SyntaxContext::empty() {
+            if span_data.ctxt == SyntaxContext::root() {
                 return end;
-            } else if end_data.ctxt == SyntaxContext::empty() {
+            } else if end_data.ctxt == SyntaxContext::root() {
                 return self;
             }
             // Both spans fall within a macro.
@@ -485,7 +490,7 @@ impl Span {
         Span::new(
             cmp::min(span_data.lo, end_data.lo),
             cmp::max(span_data.hi, end_data.hi),
-            if span_data.ctxt == SyntaxContext::empty() { end_data.ctxt } else { span_data.ctxt },
+            if span_data.ctxt == SyntaxContext::root() { end_data.ctxt } else { span_data.ctxt },
         )
     }
 
@@ -496,7 +501,7 @@ impl Span {
         Span::new(
             span.hi,
             end.lo,
-            if end.ctxt == SyntaxContext::empty() { end.ctxt } else { span.ctxt },
+            if end.ctxt == SyntaxContext::root() { end.ctxt } else { span.ctxt },
         )
     }
 
@@ -507,7 +512,7 @@ impl Span {
         Span::new(
             span.lo,
             end.lo,
-            if end.ctxt == SyntaxContext::empty() { end.ctxt } else { span.ctxt },
+            if end.ctxt == SyntaxContext::root() { end.ctxt } else { span.ctxt },
         )
     }
 
@@ -617,7 +622,7 @@ impl rustc_serialize::UseSpecializedDecodable for Span {
         d.read_struct("Span", 2, |d| {
             let lo = d.read_struct_field("lo", 0, Decodable::decode)?;
             let hi = d.read_struct_field("hi", 1, Decodable::decode)?;
-            Ok(Span::new(lo, hi, NO_EXPANSION))
+            Ok(Span::with_root_ctxt(lo, hi))
         })
     }
 }
@@ -761,8 +766,6 @@ impl From<Vec<Span>> for MultiSpan {
     }
 }
 
-pub const NO_EXPANSION: SyntaxContext = SyntaxContext::empty();
-
 /// Identifies an offset of a multi-byte character in a `SourceFile`.
 #[derive(Copy, Clone, RustcEncodable, RustcDecodable, Eq, PartialEq, Debug)]
 pub struct MultiByteChar {

From 6cb28b6617e25b74389f1cee2ec0335c2ccfb865 Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Sun, 11 Aug 2019 02:20:18 +0300
Subject: [PATCH 20/35] `Ident::with_empty_ctxt` -> `Ident::with_dummy_span`

`Ident` has had a full span rather than just a `SyntaxContext` for a long time now.
---
 src/librustc/hir/lowering.rs                  |  8 ++++----
 src/librustc/hir/lowering/expr.rs             | 14 +++++++-------
 src/librustc/hir/mod.rs                       |  6 +++---
 src/librustc/hir/print.rs                     |  2 +-
 src/librustc/traits/project.rs                |  2 +-
 src/librustc_driver/lib.rs                    |  2 +-
 src/librustc_metadata/decoder.rs              |  8 ++++----
 src/librustc_resolve/diagnostics.rs           |  2 +-
 src/librustc_resolve/late.rs                  | 16 ++++++++--------
 src/librustc_resolve/lib.rs                   | 14 +++++++-------
 src/librustc_typeck/check/mod.rs              |  2 +-
 src/librustdoc/clean/mod.rs                   |  2 +-
 src/libsyntax/attr/mod.rs                     |  4 ++--
 src/libsyntax/diagnostics/plugin.rs           |  2 +-
 src/libsyntax/ext/base.rs                     |  2 +-
 src/libsyntax/ext/build.rs                    |  2 +-
 src/libsyntax/ext/expand.rs                   |  8 ++++----
 src/libsyntax/parse/parser/module.rs          |  2 +-
 src/libsyntax/print/pprust.rs                 |  6 +++---
 src/libsyntax_ext/deriving/clone.rs           |  2 +-
 src/libsyntax_ext/deriving/debug.rs           |  4 ++--
 src/libsyntax_ext/deriving/generic/mod.rs     |  2 +-
 src/libsyntax_ext/env.rs                      |  4 ++--
 src/libsyntax_ext/global_allocator.rs         |  8 ++++----
 src/libsyntax_ext/lib.rs                      |  2 +-
 src/libsyntax_ext/plugin_macro_defs.rs        |  2 +-
 src/libsyntax_ext/proc_macro_harness.rs       |  4 ++--
 src/libsyntax_ext/standard_library_imports.rs |  6 +++---
 src/libsyntax_ext/test_harness.rs             |  6 +++---
 src/libsyntax_pos/symbol.rs                   | 10 +++++-----
 30 files changed, 77 insertions(+), 77 deletions(-)

diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 9e5d6378c4014..f942a0fb85792 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -1224,7 +1224,7 @@ impl<'a> LoweringContext<'a> {
                     P(hir::Path {
                         res,
                         segments: hir_vec![hir::PathSegment::from_ident(
-                            Ident::with_empty_ctxt(kw::SelfUpper)
+                            Ident::with_dummy_span(kw::SelfUpper)
                         )],
                         span: t.span,
                     }),
@@ -1558,7 +1558,7 @@ impl<'a> LoweringContext<'a> {
 
                     let (name, kind) = match name {
                         hir::LifetimeName::Underscore => (
-                            hir::ParamName::Plain(Ident::with_empty_ctxt(kw::UnderscoreLifetime)),
+                            hir::ParamName::Plain(Ident::with_dummy_span(kw::UnderscoreLifetime)),
                             hir::LifetimeParamKind::Elided,
                         ),
                         hir::LifetimeName::Param(param_name) => (
@@ -2002,7 +2002,7 @@ impl<'a> LoweringContext<'a> {
                         bindings: hir_vec![
                             hir::TypeBinding {
                                 hir_id: this.next_id(),
-                                ident: Ident::with_empty_ctxt(FN_OUTPUT_NAME),
+                                ident: Ident::with_dummy_span(FN_OUTPUT_NAME),
                                 kind: hir::TypeBindingKind::Equality {
                                     ty: output
                                         .as_ref()
@@ -2394,7 +2394,7 @@ impl<'a> LoweringContext<'a> {
         let future_params = P(hir::GenericArgs {
             args: hir_vec![],
             bindings: hir_vec![hir::TypeBinding {
-                ident: Ident::with_empty_ctxt(FN_OUTPUT_NAME),
+                ident: Ident::with_dummy_span(FN_OUTPUT_NAME),
                 kind: hir::TypeBindingKind::Equality {
                     ty: output_ty,
                 },
diff --git a/src/librustc/hir/lowering/expr.rs b/src/librustc/hir/lowering/expr.rs
index e3a5400942d1a..4ba61e9d4fdc8 100644
--- a/src/librustc/hir/lowering/expr.rs
+++ b/src/librustc/hir/lowering/expr.rs
@@ -552,7 +552,7 @@ impl LoweringContext<'_> {
 
         // let mut pinned = <expr>;
         let expr = P(self.lower_expr(expr));
-        let pinned_ident = Ident::with_empty_ctxt(sym::pinned);
+        let pinned_ident = Ident::with_dummy_span(sym::pinned);
         let (pinned_pat, pinned_pat_hid) = self.pat_ident_binding_mode(
             span,
             pinned_ident,
@@ -593,7 +593,7 @@ impl LoweringContext<'_> {
         let loop_node_id = self.sess.next_node_id();
         let loop_hir_id = self.lower_node_id(loop_node_id);
         let ready_arm = {
-            let x_ident = Ident::with_empty_ctxt(sym::result);
+            let x_ident = Ident::with_dummy_span(sym::result);
             let (x_pat, x_pat_hid) = self.pat_ident(span, x_ident);
             let x_expr = P(self.expr_ident(span, x_ident, x_pat_hid));
             let ready_pat = self.pat_std_enum(
@@ -1070,9 +1070,9 @@ impl LoweringContext<'_> {
         );
         head.span = desugared_span;
 
-        let iter = Ident::with_empty_ctxt(sym::iter);
+        let iter = Ident::with_dummy_span(sym::iter);
 
-        let next_ident = Ident::with_empty_ctxt(sym::__next);
+        let next_ident = Ident::with_dummy_span(sym::__next);
         let (next_pat, next_pat_hid) = self.pat_ident_binding_mode(
             desugared_span,
             next_ident,
@@ -1081,7 +1081,7 @@ impl LoweringContext<'_> {
 
         // `::std::option::Option::Some(val) => __next = val`
         let pat_arm = {
-            let val_ident = Ident::with_empty_ctxt(sym::val);
+            let val_ident = Ident::with_dummy_span(sym::val);
             let (val_pat, val_pat_hid) = self.pat_ident(pat.span, val_ident);
             let val_expr = P(self.expr_ident(pat.span, val_ident, val_pat_hid));
             let next_expr = P(self.expr_ident(pat.span, next_ident, next_pat_hid));
@@ -1247,7 +1247,7 @@ impl LoweringContext<'_> {
 
         // `Ok(val) => #[allow(unreachable_code)] val,`
         let ok_arm = {
-            let val_ident = Ident::with_empty_ctxt(sym::val);
+            let val_ident = Ident::with_dummy_span(sym::val);
             let (val_pat, val_pat_nid) = self.pat_ident(span, val_ident);
             let val_expr = P(self.expr_ident_with_attrs(
                 span,
@@ -1263,7 +1263,7 @@ impl LoweringContext<'_> {
         // `Err(err) => #[allow(unreachable_code)]
         //              return Try::from_error(From::from(err)),`
         let err_arm = {
-            let err_ident = Ident::with_empty_ctxt(sym::err);
+            let err_ident = Ident::with_dummy_span(sym::err);
             let (err_local, err_local_nid) = self.pat_ident(try_span, err_ident);
             let from_expr = {
                 let from_path = &[sym::convert, sym::From, sym::from];
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 7c2f9907217cb..57fd0be77ecff 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -202,7 +202,7 @@ impl ParamName {
         match *self {
             ParamName::Plain(ident) => ident,
             ParamName::Fresh(_) |
-            ParamName::Error => Ident::with_empty_ctxt(kw::UnderscoreLifetime),
+            ParamName::Error => Ident::with_dummy_span(kw::UnderscoreLifetime),
         }
     }
 
@@ -237,8 +237,8 @@ impl LifetimeName {
     pub fn ident(&self) -> Ident {
         match *self {
             LifetimeName::Implicit | LifetimeName::Error => Ident::invalid(),
-            LifetimeName::Underscore => Ident::with_empty_ctxt(kw::UnderscoreLifetime),
-            LifetimeName::Static => Ident::with_empty_ctxt(kw::StaticLifetime),
+            LifetimeName::Underscore => Ident::with_dummy_span(kw::UnderscoreLifetime),
+            LifetimeName::Static => Ident::with_dummy_span(kw::StaticLifetime),
             LifetimeName::Param(param_name) => param_name.ident(),
         }
     }
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index caf8220bbf432..2fd683ed83c54 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -1457,7 +1457,7 @@ impl<'a> State<'a> {
     }
 
     pub fn print_name(&mut self, name: ast::Name) {
-        self.print_ident(ast::Ident::with_empty_ctxt(name))
+        self.print_ident(ast::Ident::with_dummy_span(name))
     }
 
     pub fn print_for_decl(&mut self, loc: &hir::Local, coll: &hir::Expr) {
diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs
index 38263f26a59a0..72df45df92314 100644
--- a/src/librustc/traits/project.rs
+++ b/src/librustc/traits/project.rs
@@ -1417,7 +1417,7 @@ fn confirm_callable_candidate<'cx, 'tcx>(
                 projection_ty: ty::ProjectionTy::from_ref_and_name(
                     tcx,
                     trait_ref,
-                    Ident::with_empty_ctxt(FN_OUTPUT_NAME),
+                    Ident::with_dummy_span(FN_OUTPUT_NAME),
                 ),
                 ty: ret_type
             }
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index e9d85a53d1e42..fdd0773b73ae2 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -678,7 +678,7 @@ impl RustcDefaultCalls {
 
                     let mut cfgs = sess.parse_sess.config.iter().filter_map(|&(name, ref value)| {
                         let gated_cfg = GatedCfg::gate(&ast::MetaItem {
-                            path: ast::Path::from_ident(ast::Ident::with_empty_ctxt(name)),
+                            path: ast::Path::from_ident(ast::Ident::with_dummy_span(name)),
                             node: ast::MetaItemKind::Word,
                             span: DUMMY_SP,
                         });
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 3de9bf4da11ea..0bec31d70765f 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -569,7 +569,7 @@ impl<'a, 'tcx> CrateMetadata {
 
         ty::VariantDef::new(
             tcx,
-            Ident::with_empty_ctxt(self.item_name(index)),
+            Ident::with_dummy_span(self.item_name(index)),
             variant_did,
             ctor_did,
             data.discr,
@@ -577,7 +577,7 @@ impl<'a, 'tcx> CrateMetadata {
                 let f = self.entry(index);
                 ty::FieldDef {
                     did: self.local_def_id(index),
-                    ident: Ident::with_empty_ctxt(self.item_name(index)),
+                    ident: Ident::with_dummy_span(self.item_name(index)),
                     vis: f.visibility.decode(self)
                 }
             }).collect(),
@@ -741,7 +741,7 @@ impl<'a, 'tcx> CrateMetadata {
                         DefKind::Macro(ext.macro_kind()),
                         self.local_def_id(DefIndex::from_proc_macro_index(id)),
                     );
-                    let ident = Ident::with_empty_ctxt(name);
+                    let ident = Ident::with_dummy_span(name);
                     callback(def::Export {
                         ident: ident,
                         res: res,
@@ -783,7 +783,7 @@ impl<'a, 'tcx> CrateMetadata {
                             if let Some(kind) = self.def_kind(child_index) {
                                 callback(def::Export {
                                     res: Res::Def(kind, self.local_def_id(child_index)),
-                                    ident: Ident::with_empty_ctxt(self.item_name(child_index)),
+                                    ident: Ident::with_dummy_span(self.item_name(child_index)),
                                     vis: self.get_visibility(child_index),
                                     span: self.entry(child_index).span.decode((self, sess)),
                                 });
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index 1de67edb95c08..f824dfe8e7812 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -595,7 +595,7 @@ impl<'a> Resolver<'a> {
         where FilterFn: Fn(Res) -> bool
     {
         let mut suggestions = self.lookup_import_candidates_from_module(
-            lookup_ident, namespace, self.graph_root, Ident::with_empty_ctxt(kw::Crate), &filter_fn
+            lookup_ident, namespace, self.graph_root, Ident::with_dummy_span(kw::Crate), &filter_fn
         );
 
         if lookup_ident.span.rust_2018() {
diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index 358eaae11e712..8c15bff71018a 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -352,7 +352,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
                 self.smart_resolve_path(ty.id, qself.as_ref(), path, PathSource::Type);
             }
             TyKind::ImplicitSelf => {
-                let self_ty = Ident::with_empty_ctxt(kw::SelfUpper);
+                let self_ty = Ident::with_dummy_span(kw::SelfUpper);
                 let res = self.resolve_ident_in_lexical_scope(self_ty, TypeNS, Some(ty.id), ty.span)
                               .map_or(Res::Err, |d| d.res());
                 self.r.record_partial_res(ty.id, PartialRes::new(res));
@@ -442,7 +442,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
                 GenericParamKind::Type { ref default, .. } => {
                     found_default |= default.is_some();
                     if found_default {
-                        Some((Ident::with_empty_ctxt(param.ident.name), Res::Err))
+                        Some((Ident::with_dummy_span(param.ident.name), Res::Err))
                     } else {
                         None
                     }
@@ -459,7 +459,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
                     false
                 }
             })
-            .map(|param| (Ident::with_empty_ctxt(param.ident.name), Res::Err)));
+            .map(|param| (Ident::with_dummy_span(param.ident.name), Res::Err)));
 
         for param in &generics.params {
             match param.kind {
@@ -476,7 +476,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
                     }
 
                     // Allow all following defaults to refer to this type parameter.
-                    default_ban_rib.bindings.remove(&Ident::with_empty_ctxt(param.ident.name));
+                    default_ban_rib.bindings.remove(&Ident::with_dummy_span(param.ident.name));
                 }
                 GenericParamKind::Const { ref ty } => {
                     self.ribs[TypeNS].push(const_ty_param_ban_rib);
@@ -965,7 +965,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         let mut self_type_rib = Rib::new(NormalRibKind);
 
         // Plain insert (no renaming, since types are not currently hygienic)
-        self_type_rib.bindings.insert(Ident::with_empty_ctxt(kw::SelfUpper), self_res);
+        self_type_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), self_res);
         self.ribs[TypeNS].push(self_type_rib);
         f(self);
         self.ribs[TypeNS].pop();
@@ -976,7 +976,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
     {
         let self_res = Res::SelfCtor(impl_id);
         let mut self_type_rib = Rib::new(NormalRibKind);
-        self_type_rib.bindings.insert(Ident::with_empty_ctxt(kw::SelfUpper), self_res);
+        self_type_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), self_res);
         self.ribs[ValueNS].push(self_type_rib);
         f(self);
         self.ribs[ValueNS].pop();
@@ -1476,7 +1476,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                     self.r.trait_map.insert(id, traits);
                 }
 
-                let mut std_path = vec![Segment::from_ident(Ident::with_empty_ctxt(sym::std))];
+                let mut std_path = vec![Segment::from_ident(Ident::with_dummy_span(sym::std))];
                 std_path.extend(path);
                 if self.r.primitive_type_table.primitive_types.contains_key(&path[0].ident.name) {
                     let cl = CrateLint::No;
@@ -1507,7 +1507,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
 
     fn self_type_is_available(&mut self, span: Span) -> bool {
         let binding = self.resolve_ident_in_lexical_scope(
-            Ident::with_empty_ctxt(kw::SelfUpper),
+            Ident::with_dummy_span(kw::SelfUpper),
             TypeNS,
             None,
             span,
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 8b2e371f0f612..60a368fbb4bd6 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -985,11 +985,11 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> {
         } else {
             kw::Crate
         };
-        let segments = iter::once(Ident::with_empty_ctxt(root))
+        let segments = iter::once(Ident::with_dummy_span(root))
             .chain(
                 crate_root.into_iter()
                     .chain(components.iter().cloned())
-                    .map(Ident::with_empty_ctxt)
+                    .map(Ident::with_dummy_span)
             ).map(|i| self.new_ast_path_segment(i)).collect::<Vec<_>>();
 
         let path = ast::Path {
@@ -1060,11 +1060,11 @@ impl<'a> Resolver<'a> {
                                        .collect();
 
         if !attr::contains_name(&krate.attrs, sym::no_core) {
-            extern_prelude.insert(Ident::with_empty_ctxt(sym::core), Default::default());
+            extern_prelude.insert(Ident::with_dummy_span(sym::core), Default::default());
             if !attr::contains_name(&krate.attrs, sym::no_std) {
-                extern_prelude.insert(Ident::with_empty_ctxt(sym::std), Default::default());
+                extern_prelude.insert(Ident::with_dummy_span(sym::std), Default::default());
                 if session.rust_2018() {
-                    extern_prelude.insert(Ident::with_empty_ctxt(sym::meta), Default::default());
+                    extern_prelude.insert(Ident::with_dummy_span(sym::meta), Default::default());
                 }
             }
         }
@@ -2624,7 +2624,7 @@ impl<'a> Resolver<'a> {
         let path = if path_str.starts_with("::") {
             ast::Path {
                 span,
-                segments: iter::once(Ident::with_empty_ctxt(kw::PathRoot))
+                segments: iter::once(Ident::with_dummy_span(kw::PathRoot))
                     .chain({
                         path_str.split("::").skip(1).map(Ident::from_str)
                     })
@@ -2713,7 +2713,7 @@ fn module_to_string(module: Module<'_>) -> Option<String> {
     fn collect_mod(names: &mut Vec<Ident>, module: Module<'_>) {
         if let ModuleKind::Def(.., name) = module.kind {
             if let Some(parent) = module.parent {
-                names.push(Ident::with_empty_ctxt(name));
+                names.push(Ident::with_dummy_span(name));
                 collect_mod(names, parent);
             }
         } else {
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 92f8fb30db8ee..fc1ee649e287f 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2943,7 +2943,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             (PlaceOp::Index, false) => (self.tcx.lang_items().index_trait(), sym::index),
             (PlaceOp::Index, true) => (self.tcx.lang_items().index_mut_trait(), sym::index_mut),
         };
-        (tr, ast::Ident::with_empty_ctxt(name))
+        (tr, ast::Ident::with_dummy_span(name))
     }
 
     fn try_overloaded_place_op(&self,
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index d5becd2e1a94d..fede9e9301012 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -930,7 +930,7 @@ impl Attributes {
             if attr.check_name(sym::enable) {
                 if let Some(feat) = attr.value_str() {
                     let meta = attr::mk_name_value_item_str(
-                        Ident::with_empty_ctxt(sym::target_feature), feat, DUMMY_SP
+                        Ident::with_dummy_span(sym::target_feature), feat, DUMMY_SP
                     );
                     if let Ok(feat_cfg) = Cfg::parse(&meta) {
                         cfg &= feat_cfg;
diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs
index 85c661d320a7b..bcf03b5237a8d 100644
--- a/src/libsyntax/attr/mod.rs
+++ b/src/libsyntax/attr/mod.rs
@@ -327,7 +327,7 @@ impl Attribute {
         if self.is_sugared_doc {
             let comment = self.value_str().unwrap();
             let meta = mk_name_value_item_str(
-                Ident::with_empty_ctxt(sym::doc),
+                Ident::with_dummy_span(sym::doc),
                 Symbol::intern(&strip_doc_comment_decoration(&comment.as_str())),
                 DUMMY_SP,
             );
@@ -412,7 +412,7 @@ pub fn mk_sugared_doc_attr(text: Symbol, span: Span) -> Attribute {
     Attribute {
         id: mk_attr_id(),
         style,
-        path: Path::from_ident(Ident::with_empty_ctxt(sym::doc).with_span_pos(span)),
+        path: Path::from_ident(Ident::with_dummy_span(sym::doc).with_span_pos(span)),
         tokens: MetaItemKind::NameValue(lit).tokens(span),
         is_sugared_doc: true,
         span,
diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs
index 80591ad304df0..9618b5acfb0f1 100644
--- a/src/libsyntax/diagnostics/plugin.rs
+++ b/src/libsyntax/diagnostics/plugin.rs
@@ -172,7 +172,7 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt<'_>,
             (descriptions.len(), ecx.expr_vec(span, descriptions))
         });
 
-    let static_ = ecx.lifetime(span, Ident::with_empty_ctxt(kw::StaticLifetime));
+    let static_ = ecx.lifetime(span, Ident::with_dummy_span(kw::StaticLifetime));
     let ty_str = ecx.ty_rptr(
         span,
         ecx.ty_ident(span, ecx.ident_of("str")),
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index d9fd31db4dd60..fd6b9138fdee6 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -872,7 +872,7 @@ impl<'a> ExtCtxt<'a> {
     pub fn std_path(&self, components: &[Symbol]) -> Vec<ast::Ident> {
         let def_site = DUMMY_SP.apply_mark(self.current_expansion.id);
         iter::once(Ident::new(kw::DollarCrate, def_site))
-            .chain(components.iter().map(|&s| Ident::with_empty_ctxt(s)))
+            .chain(components.iter().map(|&s| Ident::with_dummy_span(s)))
             .collect()
     }
     pub fn name_of(&self, st: &str) -> ast::Name {
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 38f46ee207cae..e2ac4d573a1e0 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -340,7 +340,7 @@ impl<'a> ExtCtxt<'a> {
         self.expr_path(self.path_ident(span, id))
     }
     pub fn expr_self(&self, span: Span) -> P<ast::Expr> {
-        self.expr_ident(span, Ident::with_empty_ctxt(kw::SelfLower))
+        self.expr_ident(span, Ident::with_dummy_span(kw::SelfLower))
     }
 
     pub fn expr_binary(&self, sp: Span, op: ast::BinOpKind,
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index aa409199afd6d..5f4074a217ad6 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -1249,21 +1249,21 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
                             let include_info = vec![
                                 ast::NestedMetaItem::MetaItem(
                                     attr::mk_name_value_item_str(
-                                        Ident::with_empty_ctxt(sym::file),
+                                        Ident::with_dummy_span(sym::file),
                                         file,
                                         DUMMY_SP,
                                     ),
                                 ),
                                 ast::NestedMetaItem::MetaItem(
                                     attr::mk_name_value_item_str(
-                                        Ident::with_empty_ctxt(sym::contents),
+                                        Ident::with_dummy_span(sym::contents),
                                         src_interned,
                                         DUMMY_SP,
                                     ),
                                 ),
                             ];
 
-                            let include_ident = Ident::with_empty_ctxt(sym::include);
+                            let include_ident = Ident::with_dummy_span(sym::include);
                             let item = attr::mk_list_item(include_ident, include_info);
                             items.push(ast::NestedMetaItem::MetaItem(item));
                         }
@@ -1325,7 +1325,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
                 }
             }
 
-            let meta = attr::mk_list_item(Ident::with_empty_ctxt(sym::doc), items);
+            let meta = attr::mk_list_item(Ident::with_dummy_span(sym::doc), items);
             *at = attr::Attribute {
                 span: at.span,
                 id: at.id,
diff --git a/src/libsyntax/parse/parser/module.rs b/src/libsyntax/parse/parser/module.rs
index 58a7ffba948b3..3f6f87b1c44b6 100644
--- a/src/libsyntax/parse/parser/module.rs
+++ b/src/libsyntax/parse/parser/module.rs
@@ -60,7 +60,7 @@ impl<'a> Parser<'a> {
                 // Record that we fetched the mod from an external file
                 if warn {
                     let attr = attr::mk_attr_outer(
-                        attr::mk_word_item(Ident::with_empty_ctxt(sym::warn_directory_ownership)));
+                        attr::mk_word_item(Ident::with_dummy_span(sym::warn_directory_ownership)));
                     attr::mark_known(&attr);
                     attrs.push(attr);
                 }
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 5955b91384290..8a7009828bc44 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -123,13 +123,13 @@ pub fn print_crate<'a>(cm: &'a SourceMap,
         // of the feature gate, so we fake them up here.
 
         // #![feature(prelude_import)]
-        let pi_nested = attr::mk_nested_word_item(ast::Ident::with_empty_ctxt(sym::prelude_import));
-        let list = attr::mk_list_item(ast::Ident::with_empty_ctxt(sym::feature), vec![pi_nested]);
+        let pi_nested = attr::mk_nested_word_item(ast::Ident::with_dummy_span(sym::prelude_import));
+        let list = attr::mk_list_item(ast::Ident::with_dummy_span(sym::feature), vec![pi_nested]);
         let fake_attr = attr::mk_attr_inner(list);
         s.print_attribute(&fake_attr);
 
         // #![no_std]
-        let no_std_meta = attr::mk_word_item(ast::Ident::with_empty_ctxt(sym::no_std));
+        let no_std_meta = attr::mk_word_item(ast::Ident::with_dummy_span(sym::no_std));
         let fake_attr = attr::mk_attr_inner(no_std_meta);
         s.print_attribute(&fake_attr);
     }
diff --git a/src/libsyntax_ext/deriving/clone.rs b/src/libsyntax_ext/deriving/clone.rs
index d80da566185cc..5a02ae0afb969 100644
--- a/src/libsyntax_ext/deriving/clone.rs
+++ b/src/libsyntax_ext/deriving/clone.rs
@@ -129,7 +129,7 @@ fn cs_clone_shallow(name: &str,
     if is_union {
         // let _: AssertParamIsCopy<Self>;
         let self_ty =
-            cx.ty_path(cx.path_ident(trait_span, ast::Ident::with_empty_ctxt(kw::SelfUpper)));
+            cx.ty_path(cx.path_ident(trait_span, ast::Ident::with_dummy_span(kw::SelfUpper)));
         assert_ty_bounds(cx, &mut stmts, self_ty, trait_span, "AssertParamIsCopy");
     } else {
         match *substr.fields {
diff --git a/src/libsyntax_ext/deriving/debug.rs b/src/libsyntax_ext/deriving/debug.rs
index 15e93f2843a12..1d5234a9b7b4f 100644
--- a/src/libsyntax_ext/deriving/debug.rs
+++ b/src/libsyntax_ext/deriving/debug.rs
@@ -82,7 +82,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
 
                 let expr = cx.expr_method_call(span,
                                                 builder_expr.clone(),
-                                                Ident::with_empty_ctxt(sym::field),
+                                                Ident::with_dummy_span(sym::field),
                                                 vec![field]);
 
                 // Use `let _ = expr;` to avoid triggering the
@@ -106,7 +106,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
                 let field = cx.expr_addr_of(field.span, field);
                 let expr = cx.expr_method_call(span,
                                                 builder_expr.clone(),
-                                                Ident::with_empty_ctxt(sym::field),
+                                                Ident::with_dummy_span(sym::field),
                                                 vec![name, field]);
                 stmts.push(stmt_let_undescore(cx, span, expr));
             }
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index d080dc37a9268..4bf004a71e4da 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -928,7 +928,7 @@ impl<'a> MethodDef<'a> {
 
         let args = {
             let self_args = explicit_self.map(|explicit_self| {
-                let ident = Ident::with_empty_ctxt(kw::SelfLower).with_span_pos(trait_.span);
+                let ident = Ident::with_dummy_span(kw::SelfLower).with_span_pos(trait_.span);
                 ast::Arg::from_self(ThinVec::default(), explicit_self, ident)
             });
             let nonself_args = arg_types.into_iter()
diff --git a/src/libsyntax_ext/env.rs b/src/libsyntax_ext/env.rs
index 442f27c782185..9834130fa23f0 100644
--- a/src/libsyntax_ext/env.rs
+++ b/src/libsyntax_ext/env.rs
@@ -23,13 +23,13 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt<'_>,
     let sp = sp.apply_mark(cx.current_expansion.id);
     let e = match env::var(&*var.as_str()) {
         Err(..) => {
-            let lt = cx.lifetime(sp, Ident::with_empty_ctxt(kw::StaticLifetime));
+            let lt = cx.lifetime(sp, Ident::with_dummy_span(kw::StaticLifetime));
             cx.expr_path(cx.path_all(sp,
                                      true,
                                      cx.std_path(&[sym::option, sym::Option, sym::None]),
                                      vec![GenericArg::Type(cx.ty_rptr(sp,
                                                      cx.ty_ident(sp,
-                                                                 Ident::with_empty_ctxt(sym::str)),
+                                                                 Ident::with_dummy_span(sym::str)),
                                                      Some(lt),
                                                      ast::Mutability::Immutable))],
                                      vec![]))
diff --git a/src/libsyntax_ext/global_allocator.rs b/src/libsyntax_ext/global_allocator.rs
index b1f6f55732a93..d2121abe3b466 100644
--- a/src/libsyntax_ext/global_allocator.rs
+++ b/src/libsyntax_ext/global_allocator.rs
@@ -44,7 +44,7 @@ pub fn expand(
     let const_ty = ecx.ty(span, TyKind::Tup(Vec::new()));
     let const_body = ecx.expr_block(ecx.block(span, stmts));
     let const_item =
-        ecx.item_const(span, Ident::with_empty_ctxt(kw::Underscore), const_ty, const_body);
+        ecx.item_const(span, Ident::with_dummy_span(kw::Underscore), const_ty, const_body);
 
     // Return the original item and the new methods.
     vec![Annotatable::Item(item), Annotatable::Item(const_item)]
@@ -120,7 +120,7 @@ impl AllocFnFactory<'_, '_> {
     ) -> P<Expr> {
         match *ty {
             AllocatorTy::Layout => {
-                let usize = self.cx.path_ident(self.span, Ident::with_empty_ctxt(sym::usize));
+                let usize = self.cx.path_ident(self.span, Ident::with_dummy_span(sym::usize));
                 let ty_usize = self.cx.ty_path(usize);
                 let size = ident();
                 let align = ident();
@@ -178,12 +178,12 @@ impl AllocFnFactory<'_, '_> {
     }
 
     fn usize(&self) -> P<Ty> {
-        let usize = self.cx.path_ident(self.span, Ident::with_empty_ctxt(sym::usize));
+        let usize = self.cx.path_ident(self.span, Ident::with_dummy_span(sym::usize));
         self.cx.ty_path(usize)
     }
 
     fn ptr_u8(&self) -> P<Ty> {
-        let u8 = self.cx.path_ident(self.span, Ident::with_empty_ctxt(sym::u8));
+        let u8 = self.cx.path_ident(self.span, Ident::with_dummy_span(sym::u8));
         let ty_u8 = self.cx.ty_path(u8);
         self.cx.ty_ptr(self.span, ty_u8, Mutability::Mutable)
     }
diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs
index 0f3f5c0cd0eed..3ded808bb358a 100644
--- a/src/libsyntax_ext/lib.rs
+++ b/src/libsyntax_ext/lib.rs
@@ -42,7 +42,7 @@ pub mod test_harness;
 
 pub fn register_builtin_macros(resolver: &mut dyn syntax::ext::base::Resolver, edition: Edition) {
     let mut register = |name, kind| resolver.register_builtin_macro(
-        Ident::with_empty_ctxt(name), SyntaxExtension {
+        Ident::with_dummy_span(name), SyntaxExtension {
             is_builtin: true, ..SyntaxExtension::default(kind, edition)
         },
     );
diff --git a/src/libsyntax_ext/plugin_macro_defs.rs b/src/libsyntax_ext/plugin_macro_defs.rs
index a725f5e46ad1c..15737314b2239 100644
--- a/src/libsyntax_ext/plugin_macro_defs.rs
+++ b/src/libsyntax_ext/plugin_macro_defs.rs
@@ -48,7 +48,7 @@ pub fn inject(
             [sym::rustc_attrs][..].into(),
         ));
         for (name, ext) in named_exts {
-            resolver.register_builtin_macro(Ident::with_empty_ctxt(name), ext);
+            resolver.register_builtin_macro(Ident::with_dummy_span(name), ext);
             extra_items.push(plugin_macro_def(name, span));
         }
         // The `macro_rules` items must be inserted before any other items.
diff --git a/src/libsyntax_ext/proc_macro_harness.rs b/src/libsyntax_ext/proc_macro_harness.rs
index 70325539f301f..62c74b2b9c6b4 100644
--- a/src/libsyntax_ext/proc_macro_harness.rs
+++ b/src/libsyntax_ext/proc_macro_harness.rs
@@ -337,7 +337,7 @@ fn mk_decls(
     let doc = cx.meta_list(span, sym::doc, vec![hidden]);
     let doc_hidden = cx.attribute(doc);
 
-    let proc_macro = Ident::with_empty_ctxt(sym::proc_macro);
+    let proc_macro = Ident::with_dummy_span(sym::proc_macro);
     let krate = cx.item(span,
                         proc_macro,
                         Vec::new(),
@@ -349,7 +349,7 @@ fn mk_decls(
     let custom_derive = Ident::from_str("custom_derive");
     let attr = Ident::from_str("attr");
     let bang = Ident::from_str("bang");
-    let crate_kw = Ident::with_empty_ctxt(kw::Crate);
+    let crate_kw = Ident::with_dummy_span(kw::Crate);
 
     let decls = {
         let local_path = |sp: Span, name| {
diff --git a/src/libsyntax_ext/standard_library_imports.rs b/src/libsyntax_ext/standard_library_imports.rs
index 68b13bdd171a9..4382fb8af8585 100644
--- a/src/libsyntax_ext/standard_library_imports.rs
+++ b/src/libsyntax_ext/standard_library_imports.rs
@@ -32,7 +32,7 @@ pub fn inject(
         // HACK(eddyb) gensym the injected crates on the Rust 2018 edition,
         // so they don't accidentally interfere with the new import paths.
         let orig_name_sym = Symbol::intern(orig_name_str);
-        let orig_name_ident = Ident::with_empty_ctxt(orig_name_sym);
+        let orig_name_ident = Ident::with_dummy_span(orig_name_sym);
         let (rename, orig_name) = if rust_2018 {
             (orig_name_ident.gensym(), Some(orig_name_sym))
         } else {
@@ -40,7 +40,7 @@ pub fn inject(
         };
         krate.module.items.insert(0, P(ast::Item {
             attrs: vec![attr::mk_attr_outer(
-                attr::mk_word_item(ast::Ident::with_empty_ctxt(sym::macro_use))
+                attr::mk_word_item(ast::Ident::with_dummy_span(sym::macro_use))
             )],
             vis: dummy_spanned(ast::VisibilityKind::Inherited),
             node: ast::ItemKind::ExternCrate(alt_std_name.or(orig_name)),
@@ -66,7 +66,7 @@ pub fn inject(
         vis: respan(span.shrink_to_lo(), ast::VisibilityKind::Inherited),
         node: ast::ItemKind::Use(P(ast::UseTree {
             prefix: ast::Path {
-                segments: iter::once(ast::Ident::with_empty_ctxt(kw::PathRoot))
+                segments: iter::once(ast::Ident::with_dummy_span(kw::PathRoot))
                     .chain(
                         [name, "prelude", "v1"].iter().cloned()
                             .map(ast::Ident::from_str)
diff --git a/src/libsyntax_ext/test_harness.rs b/src/libsyntax_ext/test_harness.rs
index 0267637e54062..ab108290a938d 100644
--- a/src/libsyntax_ext/test_harness.rs
+++ b/src/libsyntax_ext/test_harness.rs
@@ -150,7 +150,7 @@ impl MutVisitor for EntryPointCleaner {
             EntryPointType::MainAttr |
             EntryPointType::Start =>
                 item.map(|ast::Item {id, ident, attrs, node, vis, span, tokens}| {
-                    let allow_ident = Ident::with_empty_ctxt(sym::allow);
+                    let allow_ident = Ident::with_dummy_span(sym::allow);
                     let dc_nested = attr::mk_nested_word_item(Ident::from_str("dead_code"));
                     let allow_dead_code_item = attr::mk_list_item(allow_ident, vec![dc_nested]);
                     let allow_dead_code = attr::mk_attr_outer(allow_dead_code_item);
@@ -191,7 +191,7 @@ fn mk_reexport_mod(cx: &mut TestCtxt<'_>,
                    tests: Vec<Ident>,
                    tested_submods: Vec<(Ident, Ident)>)
                    -> (P<ast::Item>, Ident) {
-    let super_ = Ident::with_empty_ctxt(kw::Super);
+    let super_ = Ident::with_dummy_span(kw::Super);
 
     let items = tests.into_iter().map(|r| {
         cx.ext_cx.item_use_simple(DUMMY_SP, dummy_spanned(ast::VisibilityKind::Public),
@@ -274,7 +274,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
         [sym::main, sym::test, sym::rustc_attrs][..].into(),
     ));
     let ecx = &cx.ext_cx;
-    let test_id = Ident::with_empty_ctxt(sym::test);
+    let test_id = Ident::with_dummy_span(sym::test);
 
     // test::test_main_static(...)
     let mut test_runner = cx.test_runner.clone().unwrap_or(
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index 6f5a458a874e1..e2d1635f31216 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -744,25 +744,25 @@ impl Ident {
         Ident { name, span }
     }
 
-    /// Constructs a new identifier with an empty syntax context.
+    /// Constructs a new identifier with a dummy span.
     #[inline]
-    pub const fn with_empty_ctxt(name: Symbol) -> Ident {
+    pub const fn with_dummy_span(name: Symbol) -> Ident {
         Ident::new(name, DUMMY_SP)
     }
 
     #[inline]
     pub fn invalid() -> Ident {
-        Ident::with_empty_ctxt(kw::Invalid)
+        Ident::with_dummy_span(kw::Invalid)
     }
 
     /// Maps an interned string to an identifier with an empty syntax context.
     pub fn from_interned_str(string: InternedString) -> Ident {
-        Ident::with_empty_ctxt(string.as_symbol())
+        Ident::with_dummy_span(string.as_symbol())
     }
 
     /// Maps a string to an identifier with an empty span.
     pub fn from_str(string: &str) -> Ident {
-        Ident::with_empty_ctxt(Symbol::intern(string))
+        Ident::with_dummy_span(Symbol::intern(string))
     }
 
     /// Maps a string and a span to an identifier.

From 73dee258c19a6e9e8249a0d7ff1db54014d0c7a1 Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Sun, 11 Aug 2019 03:00:05 +0300
Subject: [PATCH 21/35] hygiene: Remove `Option`s from functions returning
 `ExpnInfo`

The expansion info is not optional and should always exist
---
 src/librustc/lint/internal.rs          | 33 +++++---------
 src/librustc/lint/mod.rs               | 19 +++-----
 src/librustc/traits/error_reporting.rs |  8 ++--
 src/librustc/ty/query/on_disk_cache.rs | 18 +++-----
 src/librustc_codegen_ssa/back/write.rs |  5 +-
 src/librustc_lint/unused.rs            |  5 +-
 src/librustc_resolve/macros.rs         |  3 +-
 src/libsyntax/ext/base.rs              | 21 +++------
 src/libsyntax/ext/expand.rs            |  2 +-
 src/libsyntax/ext/proc_macro_server.rs |  4 +-
 src/libsyntax/parse/parser.rs          |  1 -
 src/libsyntax/source_map.rs            | 13 +++---
 src/libsyntax_pos/hygiene.rs           | 58 +++++++++---------------
 src/libsyntax_pos/lib.rs               | 63 +++++++++++---------------
 14 files changed, 98 insertions(+), 155 deletions(-)

diff --git a/src/librustc/lint/internal.rs b/src/librustc/lint/internal.rs
index d9ad34a5297f7..29106fe000bb6 100644
--- a/src/librustc/lint/internal.rs
+++ b/src/librustc/lint/internal.rs
@@ -9,7 +9,6 @@ use errors::Applicability;
 use rustc_data_structures::fx::FxHashMap;
 use syntax::ast::{Ident, Item, ItemKind};
 use syntax::symbol::{sym, Symbol};
-use syntax_pos::ExpnInfo;
 
 declare_tool_lint! {
     pub rustc::DEFAULT_HASH_TYPES,
@@ -228,30 +227,20 @@ impl EarlyLintPass for LintPassImpl {
         if let ItemKind::Impl(_, _, _, _, Some(lint_pass), _, _) = &item.node {
             if let Some(last) = lint_pass.path.segments.last() {
                 if last.ident.name == sym::LintPass {
-                    match &lint_pass.path.span.ctxt().outer_expn_info() {
-                        Some(info) if is_lint_pass_expansion(info) => {}
-                        _ => {
-                            cx.struct_span_lint(
-                                LINT_PASS_IMPL_WITHOUT_MACRO,
-                                lint_pass.path.span,
-                                "implementing `LintPass` by hand",
-                            )
-                            .help("try using `declare_lint_pass!` or `impl_lint_pass!` instead")
-                            .emit();
-                        }
+                    let expn_info = lint_pass.path.span.ctxt().outer_expn_info();
+                    let call_site = expn_info.call_site;
+                    if expn_info.kind.descr() != sym::impl_lint_pass &&
+                       call_site.ctxt().outer_expn_info().kind.descr() != sym::declare_lint_pass {
+                        cx.struct_span_lint(
+                            LINT_PASS_IMPL_WITHOUT_MACRO,
+                            lint_pass.path.span,
+                            "implementing `LintPass` by hand",
+                        )
+                        .help("try using `declare_lint_pass!` or `impl_lint_pass!` instead")
+                        .emit();
                     }
                 }
             }
         }
     }
 }
-
-fn is_lint_pass_expansion(expn_info: &ExpnInfo) -> bool {
-    if expn_info.kind.descr() == sym::impl_lint_pass {
-        true
-    } else if let Some(info) = expn_info.call_site.ctxt().outer_expn_info() {
-        info.kind.descr() == sym::declare_lint_pass
-    } else {
-        false
-    }
-}
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 8cb5b1e26d947..3729ee81f5c65 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -885,21 +885,16 @@ pub fn provide(providers: &mut Providers<'_>) {
 /// This is used to test whether a lint should not even begin to figure out whether it should
 /// be reported on the current node.
 pub fn in_external_macro(sess: &Session, span: Span) -> bool {
-    let info = match span.ctxt().outer_expn_info() {
-        Some(info) => info,
-        // no ExpnInfo means this span doesn't come from a macro
-        None => return false,
-    };
-
-    match info.kind {
+    let expn_info = span.ctxt().outer_expn_info();
+    match expn_info.kind {
         ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop) => false,
         ExpnKind::Desugaring(_) => true, // well, it's "external"
         ExpnKind::Macro(MacroKind::Bang, _) => {
-            if info.def_site.is_dummy() {
+            if expn_info.def_site.is_dummy() {
                 // dummy span for the def_site means it's an external macro
                 return true;
             }
-            match sess.source_map().span_to_snippet(info.def_site) {
+            match sess.source_map().span_to_snippet(expn_info.def_site) {
                 Ok(code) => !code.starts_with("macro_rules"),
                 // no snippet = external macro or compiler-builtin expansion
                 Err(_) => true,
@@ -911,10 +906,8 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool {
 
 /// Returns whether `span` originates in a derive macro's expansion
 pub fn in_derive_expansion(span: Span) -> bool {
-    if let Some(info) = span.ctxt().outer_expn_info() {
-        if let ExpnKind::Macro(MacroKind::Derive, _) = info.kind {
-            return true;
-        }
+    if let ExpnKind::Macro(MacroKind::Derive, _) = span.ctxt().outer_expn_info().kind {
+        return true;
     }
     false
 }
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 83bd5c56040e1..20568d4709b64 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -36,7 +36,7 @@ use errors::{Applicability, DiagnosticBuilder};
 use std::fmt;
 use syntax::ast;
 use syntax::symbol::sym;
-use syntax_pos::{DUMMY_SP, Span, ExpnInfo, ExpnKind};
+use syntax_pos::{DUMMY_SP, Span, ExpnKind};
 
 impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     pub fn report_fulfillment_errors(&self,
@@ -61,9 +61,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             // We want to ignore desugarings here: spans are equivalent even
             // if one is the result of a desugaring and the other is not.
             let mut span = error.obligation.cause.span;
-            if let Some(ExpnInfo { kind: ExpnKind::Desugaring(_), def_site, .. })
-                    = span.ctxt().outer_expn_info() {
-                span = def_site;
+            let expn_info = span.ctxt().outer_expn_info();
+            if let ExpnKind::Desugaring(_) = expn_info.kind {
+                span = expn_info.call_site;
             }
 
             error_map.entry(span).or_default().push(
diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs
index 1c5baa638c2b1..2286271b9eb4f 100644
--- a/src/librustc/ty/query/on_disk_cache.rs
+++ b/src/librustc/ty/query/on_disk_cache.rs
@@ -820,18 +820,14 @@ where
             TAG_NO_EXPANSION_INFO.encode(self)
         } else {
             let (expn_id, expn_info) = span_data.ctxt.outer_expn_with_info();
-            if let Some(expn_info) = expn_info {
-                if let Some(pos) = self.expn_info_shorthands.get(&expn_id).cloned() {
-                    TAG_EXPANSION_INFO_SHORTHAND.encode(self)?;
-                    pos.encode(self)
-                } else {
-                    TAG_EXPANSION_INFO_INLINE.encode(self)?;
-                    let pos = AbsoluteBytePos::new(self.position());
-                    self.expn_info_shorthands.insert(expn_id, pos);
-                    expn_info.encode(self)
-                }
+            if let Some(pos) = self.expn_info_shorthands.get(&expn_id).cloned() {
+                TAG_EXPANSION_INFO_SHORTHAND.encode(self)?;
+                pos.encode(self)
             } else {
-                TAG_NO_EXPANSION_INFO.encode(self)
+                TAG_EXPANSION_INFO_INLINE.encode(self)?;
+                let pos = AbsoluteBytePos::new(self.position());
+                self.expn_info_shorthands.insert(expn_id, pos);
+                expn_info.encode(self)
             }
         }
     }
diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs
index c9e4663fdbddf..240264a98220d 100644
--- a/src/librustc_codegen_ssa/back/write.rs
+++ b/src/librustc_codegen_ssa/back/write.rs
@@ -1775,10 +1775,7 @@ impl SharedEmitterMain {
                     }
                 }
                 Ok(SharedEmitterMessage::InlineAsmError(cookie, msg)) => {
-                    match ExpnId::from_u32(cookie).expn_info() {
-                        Some(ei) => sess.span_err(ei.call_site, &msg),
-                        None     => sess.err(&msg),
-                    }
+                    sess.span_err(ExpnId::from_u32(cookie).expn_info().call_site, &msg)
                 }
                 Ok(SharedEmitterMessage::AbortIfErrors) => {
                     sess.abort_if_errors();
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index 9cad8f58d41da..1bb05bda69f5b 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -517,9 +517,8 @@ impl EarlyLintPass for UnusedParens {
                 // trigger in situations that macro authors shouldn't have to care about, e.g.,
                 // when a parenthesized token tree matched in one macro expansion is matched as
                 // an expression in another and used as a fn/method argument (Issue #47775)
-                if e.span.ctxt().outer_expn_info()
-                    .map_or(false, |info| info.call_site.from_expansion()) {
-                        return;
+                if e.span.ctxt().outer_expn_info().call_site.from_expansion() {
+                    return;
                 }
                 let msg = format!("{} argument", call_kind);
                 for arg in args_to_check {
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 71e26dac57c2a..97b0f825ee94e 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -346,8 +346,7 @@ impl<'a> Resolver<'a> {
 
         // Possibly apply the macro helper hack
         if kind == Some(MacroKind::Bang) && path.len() == 1 &&
-           path[0].ident.span.ctxt().outer_expn_info()
-               .map_or(false, |info| info.local_inner_macros) {
+           path[0].ident.span.ctxt().outer_expn_info().local_inner_macros {
             let root = Ident::new(kw::DollarCrate, path[0].ident.span);
             path.insert(0, Segment::from_ident(root));
         }
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index fd6b9138fdee6..8eacb96e3ff96 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -756,10 +756,7 @@ impl<'a> ExtCtxt<'a> {
     pub fn parse_sess(&self) -> &'a parse::ParseSess { self.parse_sess }
     pub fn cfg(&self) -> &ast::CrateConfig { &self.parse_sess.config }
     pub fn call_site(&self) -> Span {
-        match self.current_expansion.id.expn_info() {
-            Some(expn_info) => expn_info.call_site,
-            None => DUMMY_SP,
-        }
+        self.current_expansion.id.expn_info().call_site
     }
     pub fn backtrace(&self) -> SyntaxContext {
         SyntaxContext::root().apply_mark(self.current_expansion.id)
@@ -772,17 +769,13 @@ impl<'a> ExtCtxt<'a> {
         let mut ctxt = self.backtrace();
         let mut last_macro = None;
         loop {
-            if ctxt.outer_expn_info().map_or(None, |info| {
-                if info.kind.descr() == sym::include {
-                    // Stop going up the backtrace once include! is encountered
-                    return None;
-                }
-                ctxt = info.call_site.ctxt();
-                last_macro = Some(info.call_site);
-                Some(())
-            }).is_none() {
-                break
+            let expn_info = ctxt.outer_expn_info();
+            // Stop going up the backtrace once include! is encountered
+            if expn_info.is_root() || expn_info.kind.descr() == sym::include {
+                break;
             }
+            ctxt = expn_info.call_site.ctxt();
+            last_macro = Some(expn_info.call_site);
         }
         last_macro
     }
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 5f4074a217ad6..6f3e8f14b0b22 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -475,7 +475,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
         }
 
         if self.cx.current_expansion.depth > self.cx.ecfg.recursion_limit {
-            let info = self.cx.current_expansion.id.expn_info().unwrap();
+            let info = self.cx.current_expansion.id.expn_info();
             let suggested_limit = self.cx.ecfg.recursion_limit * 2;
             let mut err = self.cx.struct_span_err(info.call_site,
                 &format!("recursion limit reached while expanding the macro `{}`",
diff --git a/src/libsyntax/ext/proc_macro_server.rs b/src/libsyntax/ext/proc_macro_server.rs
index fd93910004efe..d370431a5daef 100644
--- a/src/libsyntax/ext/proc_macro_server.rs
+++ b/src/libsyntax/ext/proc_macro_server.rs
@@ -362,7 +362,7 @@ pub(crate) struct Rustc<'a> {
 impl<'a> Rustc<'a> {
     pub fn new(cx: &'a ExtCtxt<'_>) -> Self {
         // No way to determine def location for a proc macro right now, so use call location.
-        let location = cx.current_expansion.id.expn_info().unwrap().call_site;
+        let location = cx.current_expansion.id.expn_info().call_site;
         let to_span = |transparency| {
             location.with_ctxt(
                 SyntaxContext::root()
@@ -677,7 +677,7 @@ impl server::Span for Rustc<'_> {
         self.sess.source_map().lookup_char_pos(span.lo()).file
     }
     fn parent(&mut self, span: Self::Span) -> Option<Self::Span> {
-        span.ctxt().outer_expn_info().map(|i| i.call_site)
+        span.parent()
     }
     fn source(&mut self, span: Self::Span) -> Self::Span {
         span.source_callsite()
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 3b0af88f6510e..89725d8b3395c 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -13,7 +13,6 @@ mod generics;
 use crate::ast::{self, AttrStyle, Attribute, Arg, BindingMode, StrStyle, SelfKind};
 use crate::ast::{FnDecl, Ident, IsAsync, MacDelimiter, Mutability, TyKind};
 use crate::ast::{Visibility, VisibilityKind, Unsafety, CrateSugar};
-use crate::ext::hygiene::SyntaxContext;
 use crate::source_map::{self, respan};
 use crate::parse::{SeqSep, literal, token};
 use crate::parse::lexer::UnmatchedBrace;
diff --git a/src/libsyntax/source_map.rs b/src/libsyntax/source_map.rs
index 74cab00d3c1eb..da7eb6add41a9 100644
--- a/src/libsyntax/source_map.rs
+++ b/src/libsyntax/source_map.rs
@@ -31,12 +31,13 @@ mod tests;
 /// otherwise return the call site span up to the `enclosing_sp` by
 /// following the `expn_info` chain.
 pub fn original_sp(sp: Span, enclosing_sp: Span) -> Span {
-    let call_site1 = sp.ctxt().outer_expn_info().map(|ei| ei.call_site);
-    let call_site2 = enclosing_sp.ctxt().outer_expn_info().map(|ei| ei.call_site);
-    match (call_site1, call_site2) {
-        (None, _) => sp,
-        (Some(call_site1), Some(call_site2)) if call_site1 == call_site2 => sp,
-        (Some(call_site1), _) => original_sp(call_site1, enclosing_sp),
+    let expn_info1 = sp.ctxt().outer_expn_info();
+    let expn_info2 = enclosing_sp.ctxt().outer_expn_info();
+    if expn_info1.is_root() ||
+       !expn_info2.is_root() && expn_info1.call_site == expn_info2.call_site {
+        sp
+    } else {
+        original_sp(expn_info1.call_site, enclosing_sp)
     }
 }
 
diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs
index c832e058cdf24..743bd437ee5b6 100644
--- a/src/libsyntax_pos/hygiene.rs
+++ b/src/libsyntax_pos/hygiene.rs
@@ -112,8 +112,8 @@ impl ExpnId {
     }
 
     #[inline]
-    pub fn expn_info(self) -> Option<ExpnInfo> {
-        HygieneData::with(|data| data.expn_info(self).cloned())
+    pub fn expn_info(self) -> ExpnInfo {
+        HygieneData::with(|data| data.expn_info(self).clone())
     }
 
     #[inline]
@@ -139,12 +139,9 @@ impl ExpnId {
     #[inline]
     pub fn looks_like_proc_macro_derive(self) -> bool {
         HygieneData::with(|data| {
-            if data.default_transparency(self) == Transparency::Opaque {
-                if let Some(expn_info) = data.expn_info(self) {
-                    if let ExpnKind::Macro(MacroKind::Derive, _) = expn_info.kind {
-                        return true;
-                    }
-                }
+            let expn_info = data.expn_info(self);
+            if let ExpnKind::Macro(MacroKind::Derive, _) = expn_info.kind {
+                return expn_info.default_transparency == Transparency::Opaque;
             }
             false
         })
@@ -190,16 +187,9 @@ impl HygieneData {
         self.expn_data[expn_id.0 as usize].parent
     }
 
-    fn expn_info(&self, expn_id: ExpnId) -> Option<&ExpnInfo> {
-        if expn_id != ExpnId::root() {
-            Some(self.expn_data[expn_id.0 as usize].expn_info.as_ref()
-                     .expect("no expansion info for an expansion ID"))
-        } else {
-            // FIXME: Some code relies on `expn_info().is_none()` meaning "no expansion".
-            // Introduce a method for checking for "no expansion" instead and always return
-            // `ExpnInfo` from this function instead of the `Option`.
-            None
-        }
+    fn expn_info(&self, expn_id: ExpnId) -> &ExpnInfo {
+        self.expn_data[expn_id.0 as usize].expn_info.as_ref()
+            .expect("no expansion info for an expansion ID")
     }
 
     fn is_descendant_of(&self, mut expn_id: ExpnId, ancestor: ExpnId) -> bool {
@@ -212,12 +202,6 @@ impl HygieneData {
         true
     }
 
-    fn default_transparency(&self, expn_id: ExpnId) -> Transparency {
-        self.expn_info(expn_id).map_or(
-            Transparency::SemiTransparent, |einfo| einfo.default_transparency
-        )
-    }
-
     fn modern(&self, ctxt: SyntaxContext) -> SyntaxContext {
         self.syntax_context_data[ctxt.0 as usize].opaque
     }
@@ -256,11 +240,7 @@ impl HygieneData {
 
     fn walk_chain(&self, mut span: Span, to: SyntaxContext) -> Span {
         while span.from_expansion() && span.ctxt() != to {
-            if let Some(info) = self.expn_info(self.outer_expn(span.ctxt())) {
-                span = info.call_site;
-            } else {
-                break;
-            }
+            span = self.expn_info(self.outer_expn(span.ctxt())).call_site;
         }
         span
     }
@@ -275,7 +255,9 @@ impl HygieneData {
 
     fn apply_mark(&mut self, ctxt: SyntaxContext, expn_id: ExpnId) -> SyntaxContext {
         assert_ne!(expn_id, ExpnId::root());
-        self.apply_mark_with_transparency(ctxt, expn_id, self.default_transparency(expn_id))
+        self.apply_mark_with_transparency(
+            ctxt, expn_id, self.expn_info(expn_id).default_transparency
+        )
     }
 
     fn apply_mark_with_transparency(&mut self, ctxt: SyntaxContext, expn_id: ExpnId,
@@ -285,8 +267,7 @@ impl HygieneData {
             return self.apply_mark_internal(ctxt, expn_id, transparency);
         }
 
-        let call_site_ctxt =
-            self.expn_info(expn_id).map_or(SyntaxContext::root(), |info| info.call_site.ctxt());
+        let call_site_ctxt = self.expn_info(expn_id).call_site.ctxt();
         let mut call_site_ctxt = if transparency == Transparency::SemiTransparent {
             self.modern(call_site_ctxt)
         } else {
@@ -581,17 +562,17 @@ impl SyntaxContext {
     /// `ctxt.outer_expn_info()` is equivalent to but faster than
     /// `ctxt.outer_expn().expn_info()`.
     #[inline]
-    pub fn outer_expn_info(self) -> Option<ExpnInfo> {
-        HygieneData::with(|data| data.expn_info(data.outer_expn(self)).cloned())
+    pub fn outer_expn_info(self) -> ExpnInfo {
+        HygieneData::with(|data| data.expn_info(data.outer_expn(self)).clone())
     }
 
     /// `ctxt.outer_expn_with_info()` is equivalent to but faster than
     /// `{ let outer = ctxt.outer_expn(); (outer, outer.expn_info()) }`.
     #[inline]
-    pub fn outer_expn_with_info(self) -> (ExpnId, Option<ExpnInfo>) {
+    pub fn outer_expn_with_info(self) -> (ExpnId, ExpnInfo) {
         HygieneData::with(|data| {
             let outer = data.outer_expn(self);
-            (outer, data.expn_info(outer).cloned())
+            (outer, data.expn_info(outer).clone())
         })
     }
 
@@ -681,6 +662,11 @@ impl ExpnInfo {
             ..ExpnInfo::default(kind, call_site, edition)
         }
     }
+
+    #[inline]
+    pub fn is_root(&self) -> bool {
+        if let ExpnKind::Root = self.kind { true } else { false }
+    }
 }
 
 /// Expansion kind.
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index 7c8539198b96e..7af426eaa13f7 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -355,20 +355,20 @@ impl Span {
     /// Returns the source span -- this is either the supplied span, or the span for
     /// the macro callsite that expanded to it.
     pub fn source_callsite(self) -> Span {
-        self.ctxt().outer_expn_info().map(|info| info.call_site.source_callsite()).unwrap_or(self)
+        let expn_info = self.ctxt().outer_expn_info();
+        if !expn_info.is_root() { expn_info.call_site.source_callsite() } else { self }
     }
 
     /// The `Span` for the tokens in the previous macro expansion from which `self` was generated,
     /// if any.
     pub fn parent(self) -> Option<Span> {
-        self.ctxt().outer_expn_info().map(|i| i.call_site)
+        let expn_info = self.ctxt().outer_expn_info();
+        if !expn_info.is_root() { Some(expn_info.call_site) } else { None }
     }
 
     /// Edition of the crate from which this span came.
     pub fn edition(self) -> edition::Edition {
-        self.ctxt().outer_expn_info().map_or_else(|| {
-            Edition::from_session()
-        }, |einfo| einfo.edition)
+        self.ctxt().outer_expn_info().edition
     }
 
     #[inline]
@@ -387,49 +387,39 @@ impl Span {
     /// else returns the `ExpnInfo` for the macro definition
     /// corresponding to the source callsite.
     pub fn source_callee(self) -> Option<ExpnInfo> {
-        fn source_callee(info: ExpnInfo) -> ExpnInfo {
-            match info.call_site.ctxt().outer_expn_info() {
-                Some(info) => source_callee(info),
-                None => info,
-            }
+        fn source_callee(expn_info: ExpnInfo) -> ExpnInfo {
+            let next_expn_info = expn_info.call_site.ctxt().outer_expn_info();
+            if !next_expn_info.is_root() { source_callee(next_expn_info) } else { expn_info }
         }
-        self.ctxt().outer_expn_info().map(source_callee)
+        let expn_info = self.ctxt().outer_expn_info();
+        if !expn_info.is_root() { Some(source_callee(expn_info)) } else { None }
     }
 
     /// Checks if a span is "internal" to a macro in which `#[unstable]`
     /// items can be used (that is, a macro marked with
     /// `#[allow_internal_unstable]`).
     pub fn allows_unstable(&self, feature: Symbol) -> bool {
-        match self.ctxt().outer_expn_info() {
-            Some(info) => info
-                .allow_internal_unstable
-                .map_or(false, |features| features.iter().any(|&f|
-                    f == feature || f == sym::allow_internal_unstable_backcompat_hack
-                )),
-            None => false,
-        }
+        self.ctxt().outer_expn_info().allow_internal_unstable.map_or(false, |features| {
+            features.iter().any(|&f| {
+                f == feature || f == sym::allow_internal_unstable_backcompat_hack
+            })
+        })
     }
 
     /// Checks if this span arises from a compiler desugaring of kind `kind`.
     pub fn is_desugaring(&self, kind: DesugaringKind) -> bool {
-        match self.ctxt().outer_expn_info() {
-            Some(info) => match info.kind {
-                ExpnKind::Desugaring(k) => k == kind,
-                _ => false,
-            },
-            None => false,
+        match self.ctxt().outer_expn_info().kind {
+            ExpnKind::Desugaring(k) => k == kind,
+            _ => false,
         }
     }
 
     /// Returns the compiler desugaring that created this span, or `None`
     /// if this span is not from a desugaring.
     pub fn desugaring_kind(&self) -> Option<DesugaringKind> {
-        match self.ctxt().outer_expn_info() {
-            Some(info) => match info.kind {
-                ExpnKind::Desugaring(k) => Some(k),
-                _ => None
-            },
-            None => None
+        match self.ctxt().outer_expn_info().kind {
+            ExpnKind::Desugaring(k) => Some(k),
+            _ => None
         }
     }
 
@@ -437,16 +427,17 @@ impl Span {
     /// can be used without triggering the `unsafe_code` lint
     //  (that is, a macro marked with `#[allow_internal_unsafe]`).
     pub fn allows_unsafe(&self) -> bool {
-        match self.ctxt().outer_expn_info() {
-            Some(info) => info.allow_internal_unsafe,
-            None => false,
-        }
+        self.ctxt().outer_expn_info().allow_internal_unsafe
     }
 
     pub fn macro_backtrace(mut self) -> Vec<MacroBacktrace> {
         let mut prev_span = DUMMY_SP;
         let mut result = vec![];
-        while let Some(info) = self.ctxt().outer_expn_info() {
+        loop {
+            let info = self.ctxt().outer_expn_info();
+            if info.is_root() {
+                break;
+            }
             // Don't print recursive invocations.
             if !info.call_site.source_equal(&prev_span) {
                 let (pre, post) = match info.kind {

From 23b82c32298002f80724a244c2483fd1e8ec1d54 Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Mon, 12 Aug 2019 21:52:37 +0300
Subject: [PATCH 22/35] resolve: Move macro resolution traces from `Module`s to
 `Resolver`

Traces already contain module info without that.
It's easy to forget to call `finalize_*` on a module.
In particular, macros enum and trait modules weren't finalized.
By happy accident macros weren't placed into those modules until now.
---
 src/librustc_resolve/build_reduced_graph.rs   |  4 +-
 src/librustc_resolve/late.rs                  |  3 --
 src/librustc_resolve/lib.rs                   | 18 +++++----
 src/librustc_resolve/macros.rs                | 14 +++----
 src/librustc_resolve/resolve_imports.rs       |  4 +-
 ...eature-gate-rustc-diagnostic-macros.stderr | 12 +++---
 .../ui/hygiene/no_implicit_prelude.stderr     | 16 ++++----
 .../local-modularized-tricky-fail-1.stderr    | 38 +++++++++----------
 .../ui/imports/shadow_builtin_macros.stderr   | 28 +++++++-------
 src/test/ui/issues/issue-49074.stderr         | 12 +++---
 .../macro-namespace-reserved-2.stderr         | 24 ++++++------
 .../ui/reserved/reserved-attr-on-macro.stderr | 12 +++---
 12 files changed, 90 insertions(+), 95 deletions(-)

diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 0a32b0c6e95db..98ee7203057d0 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -1267,9 +1267,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
 
     fn visit_attribute(&mut self, attr: &'b ast::Attribute) {
         if !attr.is_sugared_doc && is_builtin_attr(attr) {
-            self.parent_scope.module.builtin_attrs.borrow_mut().push((
-                attr.path.segments[0].ident, self.parent_scope.clone()
-            ));
+            self.r.builtin_attrs.push((attr.path.segments[0].ident, self.parent_scope.clone()));
         }
         visit::walk_attribute(self, attr);
     }
diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index 8c15bff71018a..e0869d848508b 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -574,7 +574,6 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
             self.ribs[ValueNS].push(Rib::new(ModuleRibKind(module)));
             self.ribs[TypeNS].push(Rib::new(ModuleRibKind(module)));
 
-            self.r.finalize_current_module_macro_resolutions(module);
             let ret = f(self);
 
             self.parent_scope.module = orig_module;
@@ -1227,7 +1226,6 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
             self.ribs[ValueNS].push(Rib::new(ModuleRibKind(anonymous_module)));
             self.ribs[TypeNS].push(Rib::new(ModuleRibKind(anonymous_module)));
             self.parent_scope.module = anonymous_module;
-            self.r.finalize_current_module_macro_resolutions(anonymous_module);
         } else {
             self.ribs[ValueNS].push(Rib::new(NormalRibKind));
         }
@@ -1984,7 +1982,6 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
 
 impl<'a> Resolver<'a> {
     pub(crate) fn late_resolve_crate(&mut self, krate: &Crate) {
-        self.finalize_current_module_macro_resolutions(self.graph_root);
         let mut late_resolution_visitor = LateResolutionVisitor::new(self);
         visit::walk_crate(&mut late_resolution_visitor, krate);
         for (id, span) in late_resolution_visitor.unused_labels.iter() {
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 60a368fbb4bd6..3d82ef3d58016 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -418,11 +418,6 @@ pub struct ModuleData<'a> {
     normal_ancestor_id: DefId,
 
     resolutions: RefCell<FxHashMap<(Ident, Namespace), &'a RefCell<NameResolution<'a>>>>,
-    single_segment_macro_resolutions: RefCell<Vec<(Ident, MacroKind, ParentScope<'a>,
-                                                   Option<&'a NameBinding<'a>>)>>,
-    multi_segment_macro_resolutions: RefCell<Vec<(Vec<Segment>, Span, MacroKind, ParentScope<'a>,
-                                                  Option<Res>)>>,
-    builtin_attrs: RefCell<Vec<(Ident, ParentScope<'a>)>>,
 
     // Macro invocations that can expand into items in this module.
     unresolved_invocations: RefCell<FxHashSet<ExpnId>>,
@@ -459,9 +454,6 @@ impl<'a> ModuleData<'a> {
             kind,
             normal_ancestor_id,
             resolutions: Default::default(),
-            single_segment_macro_resolutions: RefCell::new(Vec::new()),
-            multi_segment_macro_resolutions: RefCell::new(Vec::new()),
-            builtin_attrs: RefCell::new(Vec::new()),
             unresolved_invocations: Default::default(),
             no_implicit_prelude: false,
             glob_importers: RefCell::new(Vec::new()),
@@ -896,6 +888,12 @@ pub struct Resolver<'a> {
     local_macro_def_scopes: FxHashMap<NodeId, Module<'a>>,
     unused_macros: NodeMap<Span>,
     proc_macro_stubs: NodeSet,
+    /// Traces collected during macro resolution and validated when it's complete.
+    single_segment_macro_resolutions: Vec<(Ident, MacroKind, ParentScope<'a>,
+                                           Option<&'a NameBinding<'a>>)>,
+    multi_segment_macro_resolutions: Vec<(Vec<Segment>, Span, MacroKind, ParentScope<'a>,
+                                          Option<Res>)>,
+    builtin_attrs: Vec<(Ident, ParentScope<'a>)>,
     /// Some built-in derives mark items they are applied to so they are treated specially later.
     /// Derive macros cannot modify the item themselves and have to store the markers in the global
     /// context, so they attach the markers to derive container IDs using this resolver table.
@@ -1151,6 +1149,9 @@ impl<'a> Resolver<'a> {
             struct_constructors: Default::default(),
             unused_macros: Default::default(),
             proc_macro_stubs: Default::default(),
+            single_segment_macro_resolutions: Default::default(),
+            multi_segment_macro_resolutions: Default::default(),
+            builtin_attrs: Default::default(),
             special_derives: Default::default(),
             active_features:
                 features.declared_lib_features.iter().map(|(feat, ..)| *feat)
@@ -1203,6 +1204,7 @@ impl<'a> Resolver<'a> {
     /// Entry point to crate resolution.
     pub fn resolve_crate(&mut self, krate: &Crate) {
         ImportResolver { r: self }.finalize_imports();
+        self.finalize_macro_resolutions();
 
         self.late_resolve_crate(krate);
 
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 97b0f825ee94e..f54f395063c2c 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -366,7 +366,7 @@ impl<'a> Resolver<'a> {
 
             if trace {
                 let kind = kind.expect("macro kind must be specified if tracing is enabled");
-                parent_scope.module.multi_segment_macro_resolutions.borrow_mut()
+                self.multi_segment_macro_resolutions
                     .push((path, path_span, kind, parent_scope.clone(), res.ok()));
             }
 
@@ -383,7 +383,7 @@ impl<'a> Resolver<'a> {
 
             if trace {
                 let kind = kind.expect("macro kind must be specified if tracing is enabled");
-                parent_scope.module.single_segment_macro_resolutions.borrow_mut()
+                self.single_segment_macro_resolutions
                     .push((path[0].ident, kind, parent_scope.clone(), binding.ok()));
             }
 
@@ -693,7 +693,7 @@ impl<'a> Resolver<'a> {
         }
     }
 
-    pub fn finalize_current_module_macro_resolutions(&mut self, module: Module<'a>) {
+    crate fn finalize_macro_resolutions(&mut self) {
         let check_consistency = |this: &mut Self, path: &[Segment], span, kind: MacroKind,
                                  initial_res: Option<Res>, res: Res| {
             if let Some(initial_res) = initial_res {
@@ -729,8 +729,7 @@ impl<'a> Resolver<'a> {
             }
         };
 
-        let macro_resolutions =
-            mem::take(&mut *module.multi_segment_macro_resolutions.borrow_mut());
+        let macro_resolutions = mem::take(&mut self.multi_segment_macro_resolutions);
         for (mut path, path_span, kind, parent_scope, initial_res) in macro_resolutions {
             // FIXME: Path resolution will ICE if segment IDs present.
             for seg in &mut path { seg.id = None; }
@@ -757,8 +756,7 @@ impl<'a> Resolver<'a> {
             }
         }
 
-        let macro_resolutions =
-            mem::take(&mut *module.single_segment_macro_resolutions.borrow_mut());
+        let macro_resolutions = mem::take(&mut self.single_segment_macro_resolutions);
         for (ident, kind, parent_scope, initial_binding) in macro_resolutions {
             match self.early_resolve_ident_in_lexical_scope(ident, ScopeSet::Macro(kind),
                                                             &parent_scope, true, true, ident.span) {
@@ -783,7 +781,7 @@ impl<'a> Resolver<'a> {
             }
         }
 
-        let builtin_attrs = mem::take(&mut *module.builtin_attrs.borrow_mut());
+        let builtin_attrs = mem::take(&mut self.builtin_attrs);
         for (ident, parent_scope) in builtin_attrs {
             let _ = self.early_resolve_ident_in_lexical_scope(
                 ident, ScopeSet::Macro(MacroKind::Attr), &parent_scope, true, true, ident.span
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index 00e89f0fdae0a..ef8fcc9ba8a55 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -848,7 +848,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
         directive.vis.set(orig_vis);
         let module = match path_res {
             PathResult::Module(module) => {
-                // Consistency checks, analogous to `finalize_current_module_macro_resolutions`.
+                // Consistency checks, analogous to `finalize_macro_resolutions`.
                 if let Some(initial_module) = directive.imported_module.get() {
                     if !ModuleOrUniformRoot::same_def(module, initial_module) && no_ambiguity {
                         span_bug!(directive.span, "inconsistent resolution for an import");
@@ -973,7 +973,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
 
             match binding {
                 Ok(binding) => {
-                    // Consistency checks, analogous to `finalize_current_module_macro_resolutions`.
+                    // Consistency checks, analogous to `finalize_macro_resolutions`.
                     let initial_res = source_bindings[ns].get().map(|initial_binding| {
                         all_ns_err = false;
                         if let Some(target_binding) = target_bindings[ns].get() {
diff --git a/src/test/ui/feature-gates/feature-gate-rustc-diagnostic-macros.stderr b/src/test/ui/feature-gates/feature-gate-rustc-diagnostic-macros.stderr
index 478bc09f29192..676b8b9f056c1 100644
--- a/src/test/ui/feature-gates/feature-gate-rustc-diagnostic-macros.stderr
+++ b/src/test/ui/feature-gates/feature-gate-rustc-diagnostic-macros.stderr
@@ -4,17 +4,17 @@ error: cannot find macro `__build_diagnostic_array!` in this scope
 LL | __build_diagnostic_array!(DIAGNOSTICS);
    | ^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: cannot find macro `__register_diagnostic!` in this scope
-  --> $DIR/feature-gate-rustc-diagnostic-macros.rs:4:1
-   |
-LL | __register_diagnostic!(E0001);
-   | ^^^^^^^^^^^^^^^^^^^^^
-
 error: cannot find macro `__diagnostic_used!` in this scope
   --> $DIR/feature-gate-rustc-diagnostic-macros.rs:8:5
    |
 LL |     __diagnostic_used!(E0001);
    |     ^^^^^^^^^^^^^^^^^
 
+error: cannot find macro `__register_diagnostic!` in this scope
+  --> $DIR/feature-gate-rustc-diagnostic-macros.rs:4:1
+   |
+LL | __register_diagnostic!(E0001);
+   | ^^^^^^^^^^^^^^^^^^^^^
+
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/hygiene/no_implicit_prelude.stderr b/src/test/ui/hygiene/no_implicit_prelude.stderr
index a89176fe6907b..643f803f62049 100644
--- a/src/test/ui/hygiene/no_implicit_prelude.stderr
+++ b/src/test/ui/hygiene/no_implicit_prelude.stderr
@@ -1,3 +1,11 @@
+error: cannot find macro `panic!` in this scope
+  --> $DIR/no_implicit_prelude.rs:16:9
+   |
+LL |         assert_eq!(0, 0);
+   |         ^^^^^^^^^^^^^^^^^
+   |
+   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
 error[E0433]: failed to resolve: use of undeclared type or module `Vec`
   --> $DIR/no_implicit_prelude.rs:11:9
    |
@@ -7,14 +15,6 @@ LL |     fn f() { ::bar::m!(); }
 LL |         Vec::new();
    |         ^^^ use of undeclared type or module `Vec`
 
-error: cannot find macro `panic!` in this scope
-  --> $DIR/no_implicit_prelude.rs:16:9
-   |
-LL |         assert_eq!(0, 0);
-   |         ^^^^^^^^^^^^^^^^^
-   |
-   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
-
 error[E0599]: no method named `clone` found for type `()` in the current scope
   --> $DIR/no_implicit_prelude.rs:12:12
    |
diff --git a/src/test/ui/imports/local-modularized-tricky-fail-1.stderr b/src/test/ui/imports/local-modularized-tricky-fail-1.stderr
index 5afdd8889ae7d..7d013828bd908 100644
--- a/src/test/ui/imports/local-modularized-tricky-fail-1.stderr
+++ b/src/test/ui/imports/local-modularized-tricky-fail-1.stderr
@@ -21,25 +21,6 @@ LL | use inner1::*;
    |     ^^^^^^^^^
    = help: consider adding an explicit import of `exported` to disambiguate
 
-error[E0659]: `include` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
-  --> $DIR/local-modularized-tricky-fail-1.rs:46:1
-   |
-LL | include!();
-   | ^^^^^^^ ambiguous name
-   |
-   = note: `include` could refer to a macro from prelude
-note: `include` could also refer to the macro defined here
-  --> $DIR/local-modularized-tricky-fail-1.rs:17:5
-   |
-LL | /     macro_rules! include {
-LL | |         () => ()
-LL | |     }
-   | |_____^
-...
-LL |       define_include!();
-   |       ------------------ in this macro invocation
-   = help: use `crate::include` to refer to this macro unambiguously
-
 error[E0659]: `panic` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
   --> $DIR/local-modularized-tricky-fail-1.rs:35:5
    |
@@ -59,6 +40,25 @@ LL |       define_panic!();
    |       ---------------- in this macro invocation
    = help: use `crate::panic` to refer to this macro unambiguously
 
+error[E0659]: `include` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
+  --> $DIR/local-modularized-tricky-fail-1.rs:46:1
+   |
+LL | include!();
+   | ^^^^^^^ ambiguous name
+   |
+   = note: `include` could refer to a macro from prelude
+note: `include` could also refer to the macro defined here
+  --> $DIR/local-modularized-tricky-fail-1.rs:17:5
+   |
+LL | /     macro_rules! include {
+LL | |         () => ()
+LL | |     }
+   | |_____^
+...
+LL |       define_include!();
+   |       ------------------ in this macro invocation
+   = help: use `crate::include` to refer to this macro unambiguously
+
 error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0659`.
diff --git a/src/test/ui/imports/shadow_builtin_macros.stderr b/src/test/ui/imports/shadow_builtin_macros.stderr
index c84226ef313c2..2f2ab20cdf077 100644
--- a/src/test/ui/imports/shadow_builtin_macros.stderr
+++ b/src/test/ui/imports/shadow_builtin_macros.stderr
@@ -13,20 +13,6 @@ LL |     use foo::*;
    = help: consider adding an explicit import of `panic` to disambiguate
    = help: or use `self::panic` to refer to this macro unambiguously
 
-error[E0659]: `panic` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
-  --> $DIR/shadow_builtin_macros.rs:20:14
-   |
-LL |     fn f() { panic!(); }
-   |              ^^^^^ ambiguous name
-   |
-   = note: `panic` could refer to a macro from prelude
-note: `panic` could also refer to the macro imported here
-  --> $DIR/shadow_builtin_macros.rs:19:26
-   |
-LL |     ::two_macros::m!(use foo::panic;);
-   |                          ^^^^^^^^^^
-   = help: use `self::panic` to refer to this macro unambiguously
-
 error[E0659]: `panic` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
   --> $DIR/shadow_builtin_macros.rs:33:5
    |
@@ -62,6 +48,20 @@ note: `n` could also refer to the macro imported here
 LL | #[macro_use(n)]
    |             ^
 
+error[E0659]: `panic` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
+  --> $DIR/shadow_builtin_macros.rs:20:14
+   |
+LL |     fn f() { panic!(); }
+   |              ^^^^^ ambiguous name
+   |
+   = note: `panic` could refer to a macro from prelude
+note: `panic` could also refer to the macro imported here
+  --> $DIR/shadow_builtin_macros.rs:19:26
+   |
+LL |     ::two_macros::m!(use foo::panic;);
+   |                          ^^^^^^^^^^
+   = help: use `self::panic` to refer to this macro unambiguously
+
 error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0659`.
diff --git a/src/test/ui/issues/issue-49074.stderr b/src/test/ui/issues/issue-49074.stderr
index c557255ab502e..e0d3bb3ecc2e1 100644
--- a/src/test/ui/issues/issue-49074.stderr
+++ b/src/test/ui/issues/issue-49074.stderr
@@ -1,9 +1,3 @@
-error: cannot find attribute macro `marco_use` in this scope
-  --> $DIR/issue-49074.rs:3:3
-   |
-LL | #[marco_use] // typo
-   |   ^^^^^^^^^ help: a built-in attribute with a similar name exists: `macro_use`
-
 error: cannot find macro `bar!` in this scope
   --> $DIR/issue-49074.rs:12:4
    |
@@ -12,5 +6,11 @@ LL |    bar!();
    |
    = help: have you added the `#[macro_use]` on the module/import?
 
+error: cannot find attribute macro `marco_use` in this scope
+  --> $DIR/issue-49074.rs:3:3
+   |
+LL | #[marco_use] // typo
+   |   ^^^^^^^^^ help: a built-in attribute with a similar name exists: `macro_use`
+
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr b/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr
index b2f124788286d..0c863e919670d 100644
--- a/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr
+++ b/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr
@@ -88,18 +88,6 @@ error: expected derive macro, found macro `crate::my_macro`
 LL | #[derive(crate::my_macro)]
    |          ^^^^^^^^^^^^^^^ not a derive macro
 
-error: cannot find attribute macro `my_macro` in this scope
-  --> $DIR/macro-namespace-reserved-2.rs:38:3
-   |
-LL | #[my_macro]
-   |   ^^^^^^^^
-
-error: cannot find derive macro `my_macro` in this scope
-  --> $DIR/macro-namespace-reserved-2.rs:48:10
-   |
-LL | #[derive(my_macro)]
-   |          ^^^^^^^^
-
 error: cannot find macro `my_macro_attr!` in this scope
   --> $DIR/macro-namespace-reserved-2.rs:28:5
    |
@@ -112,5 +100,17 @@ error: cannot find macro `MyTrait!` in this scope
 LL |     MyTrait!();
    |     ^^^^^^^
 
+error: cannot find attribute macro `my_macro` in this scope
+  --> $DIR/macro-namespace-reserved-2.rs:38:3
+   |
+LL | #[my_macro]
+   |   ^^^^^^^^
+
+error: cannot find derive macro `my_macro` in this scope
+  --> $DIR/macro-namespace-reserved-2.rs:48:10
+   |
+LL | #[derive(my_macro)]
+   |          ^^^^^^^^
+
 error: aborting due to 19 previous errors
 
diff --git a/src/test/ui/reserved/reserved-attr-on-macro.stderr b/src/test/ui/reserved/reserved-attr-on-macro.stderr
index d4b97d290ea89..856162b318dea 100644
--- a/src/test/ui/reserved/reserved-attr-on-macro.stderr
+++ b/src/test/ui/reserved/reserved-attr-on-macro.stderr
@@ -7,12 +7,6 @@ LL | #[rustc_attribute_should_be_reserved]
    = note: for more information, see https://github.com/rust-lang/rust/issues/29642
    = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
 
-error: cannot find attribute macro `rustc_attribute_should_be_reserved` in this scope
-  --> $DIR/reserved-attr-on-macro.rs:1:3
-   |
-LL | #[rustc_attribute_should_be_reserved]
-   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
 error: cannot determine resolution for the macro `foo`
   --> $DIR/reserved-attr-on-macro.rs:10:5
    |
@@ -21,6 +15,12 @@ LL |     foo!();
    |
    = note: import resolution is stuck, try simplifying macro imports
 
+error: cannot find attribute macro `rustc_attribute_should_be_reserved` in this scope
+  --> $DIR/reserved-attr-on-macro.rs:1:3
+   |
+LL | #[rustc_attribute_should_be_reserved]
+   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
 error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0658`.

From cfbb60bf6d83fbcfcca1f2919131aa39fb997b53 Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Mon, 12 Aug 2019 21:55:42 +0300
Subject: [PATCH 23/35] resolve: Do not "normalize away" trait/enum modules
 prematurely

The previous approach was brittle - what would happen if `ParentScope` wasn't created by `invoc_parent_scope`?
That's exactly the case for various uses of `ParentScope` in diagnostics and in built-in attribute validation.
---
 src/librustc_resolve/lib.rs    | 8 +++++---
 src/librustc_resolve/macros.rs | 2 +-
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 3d82ef3d58016..6bb2cd037708f 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -1321,13 +1321,15 @@ impl<'a> Resolver<'a> {
             ScopeSet::AbsolutePath(ns) => (ns, true),
             ScopeSet::Macro(_) => (MacroNS, false),
         };
+        // Jump out of trait or enum modules, they do not act as scopes.
+        let module = parent_scope.module.nearest_item_scope();
         let mut scope = match ns {
             _ if is_absolute_path => Scope::CrateRoot,
-            TypeNS | ValueNS => Scope::Module(parent_scope.module),
+            TypeNS | ValueNS => Scope::Module(module),
             MacroNS => Scope::DeriveHelpers,
         };
         let mut ident = ident.modern();
-        let mut use_prelude = !parent_scope.module.no_implicit_prelude;
+        let mut use_prelude = !module.no_implicit_prelude;
 
         loop {
             let visit = match scope {
@@ -1360,7 +1362,7 @@ impl<'a> Resolver<'a> {
                     LegacyScope::Invocation(invoc) => Scope::MacroRules(
                         invoc.output_legacy_scope.get().unwrap_or(invoc.parent_legacy_scope)
                     ),
-                    LegacyScope::Empty => Scope::Module(parent_scope.module),
+                    LegacyScope::Empty => Scope::Module(module),
                 }
                 Scope::CrateRoot => match ns {
                     TypeNS => {
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index f54f395063c2c..6d882a6e194df 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -258,7 +258,7 @@ impl<'a> Resolver<'a> {
     fn invoc_parent_scope(&self, invoc_id: ExpnId, derives: Vec<ast::Path>) -> ParentScope<'a> {
         let invoc = self.invocations[&invoc_id];
         ParentScope {
-            module: invoc.module.nearest_item_scope(),
+            module: invoc.module,
             expansion: invoc_id.parent(),
             legacy: invoc.parent_legacy_scope,
             derives,

From 1a1557c28501d256f3a21099d17a73e1d2c36aa0 Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Mon, 12 Aug 2019 23:19:36 +0300
Subject: [PATCH 24/35] resolve: Add `ParentScope::default`, eliminate
 `dummy_parent_scope`

Remove some unnecessary parameters from functions
---
 src/librustc_resolve/build_reduced_graph.rs   | 17 +++++++---------
 src/librustc_resolve/late.rs                  |  2 +-
 src/librustc_resolve/lib.rs                   | 19 ++++++++++++++----
 src/librustc_resolve/macros.rs                | 20 ++++++-------------
 .../passes/collect_intra_doc_links.rs         |  3 ++-
 5 files changed, 31 insertions(+), 30 deletions(-)

diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 98ee7203057d0..016ec55947aff 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -163,8 +163,8 @@ impl<'a> Resolver<'a> {
         let def_id = module.def_id().unwrap();
         for child in self.cstore.item_children_untracked(def_id, self.session) {
             let child = child.map_id(|_| panic!("unexpected id"));
-            BuildReducedGraphVisitor { parent_scope: self.dummy_parent_scope(), r: self }
-                .build_reduced_graph_for_external_crate_res(module, child);
+            BuildReducedGraphVisitor { parent_scope: ParentScope::default(module), r: self }
+                .build_reduced_graph_for_external_crate_res(child);
         }
         module.populated.set(true)
     }
@@ -706,7 +706,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                 self.r.define(parent, ident, TypeNS, (module, vis, sp, expansion));
 
                 for variant in &(*enum_definition).variants {
-                    self.build_reduced_graph_for_variant(variant, module, vis, expansion);
+                    self.build_reduced_graph_for_variant(variant, module, vis);
                 }
             }
 
@@ -797,8 +797,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
     fn build_reduced_graph_for_variant(&mut self,
                                        variant: &Variant,
                                        parent: Module<'a>,
-                                       vis: ty::Visibility,
-                                       expn_id: ExpnId) {
+                                       vis: ty::Visibility) {
+        let expn_id = self.parent_scope.expansion;
         let ident = variant.ident;
 
         // Define a name in the type namespace.
@@ -861,11 +861,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
     }
 
     /// Builds the reduced graph for a single item in an external crate.
-    fn build_reduced_graph_for_external_crate_res(
-        &mut self,
-        parent: Module<'a>,
-        child: Export<ast::NodeId>,
-    ) {
+    fn build_reduced_graph_for_external_crate_res(&mut self, child: Export<ast::NodeId>) {
+        let parent = self.parent_scope.module;
         let Export { ident, res, vis, span } = child;
         // FIXME: We shouldn't create the gensym here, it should come from metadata,
         // but metadata cannot encode gensyms currently, so we create it here.
diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index e0869d848508b..fbd9f1d48e5e6 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -501,8 +501,8 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
     fn new(resolver: &'b mut Resolver<'a>) -> LateResolutionVisitor<'a, 'b> {
         // During late resolution we only track the module component of the parent scope,
         // although it may be useful to track other components as well for diagnostics.
-        let parent_scope = resolver.dummy_parent_scope();
         let graph_root = resolver.graph_root;
+        let parent_scope = ParentScope::default(graph_root);
         LateResolutionVisitor {
             r: resolver,
             parent_scope,
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 6bb2cd037708f..788252c55fc7d 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -130,6 +130,17 @@ pub struct ParentScope<'a> {
     derives: Vec<ast::Path>,
 }
 
+impl<'a> ParentScope<'a> {
+    pub fn default(module: Module<'a>) -> ParentScope<'a> {
+        ParentScope {
+            module,
+            expansion: ExpnId::root(),
+            legacy: LegacyScope::Empty,
+            derives: Vec::new(),
+        }
+    }
+}
+
 #[derive(Eq)]
 struct BindingError {
     name: Name,
@@ -799,7 +810,7 @@ pub struct Resolver<'a> {
 
     pub definitions: Definitions,
 
-    graph_root: Module<'a>,
+    pub graph_root: Module<'a>,
 
     prelude: Option<Module<'a>>,
     pub extern_prelude: FxHashMap<Ident, ExternPreludeEntry<'a>>,
@@ -995,7 +1006,7 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> {
             segments,
         };
 
-        let parent_scope = &self.dummy_parent_scope();
+        let parent_scope = &ParentScope::default(self.graph_root);
         let res = match self.resolve_ast_path(&path, ns, parent_scope) {
             Ok(res) => res,
             Err((span, error)) => {
@@ -1069,7 +1080,7 @@ impl<'a> Resolver<'a> {
 
         let mut invocations = FxHashMap::default();
         invocations.insert(ExpnId::root(),
-                           arenas.alloc_invocation_data(InvocationData::root(graph_root)));
+                           arenas.alloc_invocation_data(InvocationData::default(graph_root)));
 
         let mut macro_defs = FxHashMap::default();
         macro_defs.insert(ExpnId::root(), root_def_id);
@@ -2649,7 +2660,7 @@ impl<'a> Resolver<'a> {
             let def_id = self.definitions.local_def_id(module_id);
             self.module_map.get(&def_id).copied().unwrap_or(self.graph_root)
         });
-        let parent_scope = &ParentScope { module, ..self.dummy_parent_scope() };
+        let parent_scope = &ParentScope::default(module);
         let res = self.resolve_ast_path(&path, ns, parent_scope).map_err(|_| ())?;
         Ok((path, res))
     }
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 6d882a6e194df..754983e3bd42c 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -43,9 +43,9 @@ pub struct InvocationData<'a> {
 }
 
 impl<'a> InvocationData<'a> {
-    pub fn root(graph_root: Module<'a>) -> Self {
+    pub fn default(module: Module<'a>) -> Self {
         InvocationData {
-            module: graph_root,
+            module,
             parent_legacy_scope: LegacyScope::Empty,
             output_legacy_scope: Cell::new(None),
         }
@@ -120,17 +120,13 @@ impl<'a> base::Resolver for Resolver<'a> {
     }
 
     fn get_module_scope(&mut self, id: ast::NodeId) -> ExpnId {
-        let span = DUMMY_SP.fresh_expansion(ExpnId::root(), ExpnInfo::default(
+        let expn_id = ExpnId::fresh(ExpnId::root(), Some(ExpnInfo::default(
             ExpnKind::Macro(MacroKind::Attr, sym::test_case), DUMMY_SP, self.session.edition()
-        ));
-        let expn_id = span.ctxt().outer_expn();
+        )));
         let module = self.module_map[&self.definitions.local_def_id(id)];
+        let invocation_data = self.arenas.alloc_invocation_data(InvocationData::default(module));
         self.definitions.set_invocation_parent(expn_id, module.def_id().unwrap().index);
-        self.invocations.insert(expn_id, self.arenas.alloc_invocation_data(InvocationData {
-            module,
-            parent_legacy_scope: LegacyScope::Empty,
-            output_legacy_scope: Cell::new(None),
-        }));
+        self.invocations.insert(expn_id, invocation_data);
         expn_id
     }
 
@@ -251,10 +247,6 @@ impl<'a> base::Resolver for Resolver<'a> {
 }
 
 impl<'a> Resolver<'a> {
-    pub fn dummy_parent_scope(&self) -> ParentScope<'a> {
-        self.invoc_parent_scope(ExpnId::root(), Vec::new())
-    }
-
     fn invoc_parent_scope(&self, invoc_id: ExpnId, derives: Vec<ast::Path>) -> ParentScope<'a> {
         let invoc = self.invocations[&invoc_id];
         ParentScope {
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 5c9fac7eab421..5767b5b3b46a5 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -4,6 +4,7 @@ use rustc::hir::def_id::DefId;
 use rustc::hir;
 use rustc::lint as lint;
 use rustc::ty;
+use rustc_resolve::ParentScope;
 use syntax;
 use syntax::ast::{self, Ident};
 use syntax::ext::base::SyntaxExtensionKind;
@@ -431,7 +432,7 @@ fn macro_resolve(cx: &DocContext<'_>, path_str: &str) -> Option<Res> {
     let path = ast::Path::from_ident(Ident::from_str(path_str));
     cx.enter_resolver(|resolver| {
         if let Ok((Some(ext), res)) = resolver.resolve_macro_path(
-            &path, None, &resolver.dummy_parent_scope(), false, false
+            &path, None, &ParentScope::default(resolver.graph_root), false, false
         ) {
             if let SyntaxExtensionKind::LegacyBang { .. } = ext.kind {
                 return Some(res.map_id(|_| panic!("unexpected id")));

From 59dd07ae2bbc8d6c46bdb5f3d5b93a6729848311 Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Mon, 12 Aug 2019 23:39:49 +0300
Subject: [PATCH 25/35] resolve: Eliminate `InvocationData`

It was very similar to `ParentScope` and mostly could be replaced by it.
---
 src/librustc_resolve/build_reduced_graph.rs | 23 +++---
 src/librustc_resolve/lib.rs                 | 29 ++++---
 src/librustc_resolve/macros.rs              | 92 +++++++--------------
 3 files changed, 53 insertions(+), 91 deletions(-)

diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 016ec55947aff..51a0a74568851 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -3,7 +3,7 @@
 //! Here we build the "reduced graph": the graph of the module tree without
 //! any imports resolved.
 
-use crate::macros::{InvocationData, LegacyBinding, LegacyScope};
+use crate::macros::{LegacyBinding, LegacyScope};
 use crate::resolve_imports::ImportDirective;
 use crate::resolve_imports::ImportDirectiveSubclass::{self, GlobImport, SingleImport};
 use crate::{Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, Segment, ToNameBinding};
@@ -1063,20 +1063,17 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
         false
     }
 
-    fn visit_invoc(&mut self, id: ast::NodeId) -> &'a InvocationData<'a> {
+    fn visit_invoc(&mut self, id: ast::NodeId) -> LegacyScope<'a> {
         let invoc_id = id.placeholder_to_expn_id();
 
-        self.parent_scope.module.unresolved_invocations.borrow_mut().insert(invoc_id);
+        let parent_scope = self.parent_scope.clone();
+        parent_scope.module.unresolved_invocations.borrow_mut().insert(invoc_id);
 
-        let invocation_data = self.r.arenas.alloc_invocation_data(InvocationData {
-            module: self.parent_scope.module,
-            parent_legacy_scope: self.parent_scope.legacy,
-            output_legacy_scope: Cell::new(None),
-        });
-        let old_invocation_data = self.r.invocations.insert(invoc_id, invocation_data);
-        assert!(old_invocation_data.is_none(), "invocation data is reset for an invocation");
+        let old_parent_scope =
+            self.r.invocation_parent_scopes.insert(invoc_id, parent_scope.clone());
+        assert!(old_parent_scope.is_none(), "invocation data is reset for an invocation");
 
-        invocation_data
+        LegacyScope::Invocation(invoc_id)
     }
 
     fn proc_macro_stub(item: &ast::Item) -> Option<(MacroKind, Ident, Span)> {
@@ -1177,7 +1174,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
                 return
             }
             ItemKind::Mac(..) => {
-                self.parent_scope.legacy = LegacyScope::Invocation(self.visit_invoc(item.id));
+                self.parent_scope.legacy = self.visit_invoc(item.id);
                 return
             }
             ItemKind::Mod(..) => self.contains_macro_use(&item.attrs),
@@ -1196,7 +1193,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
 
     fn visit_stmt(&mut self, stmt: &'b ast::Stmt) {
         if let ast::StmtKind::Mac(..) = stmt.node {
-            self.parent_scope.legacy = LegacyScope::Invocation(self.visit_invoc(stmt.id));
+            self.parent_scope.legacy = self.visit_invoc(stmt.id);
         } else {
             visit::walk_stmt(self, stmt);
         }
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 788252c55fc7d..85f8d07bf9bd5 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -54,7 +54,7 @@ use diagnostics::{Suggestion, ImportSuggestion};
 use diagnostics::{find_span_of_binding_until_next_binding, extend_span_to_previous_binding};
 use late::{PathSource, Rib, RibKind::*};
 use resolve_imports::{ImportDirective, ImportDirectiveSubclass, NameResolution, ImportResolver};
-use macros::{InvocationData, LegacyBinding, LegacyScope};
+use macros::{LegacyBinding, LegacyScope};
 
 type Res = def::Res<NodeId>;
 
@@ -911,9 +911,12 @@ pub struct Resolver<'a> {
     /// FIXME: Find a way for `PartialEq` and `Eq` to emulate `#[structural_match]`
     /// by marking the produced impls rather than the original items.
     special_derives: FxHashMap<ExpnId, SpecialDerives>,
-
-    /// Maps the `ExpnId` of an expansion to its containing module or block.
-    invocations: FxHashMap<ExpnId, &'a InvocationData<'a>>,
+    /// Parent scopes in which the macros were invoked.
+    /// FIXME: `derives` are missing in these parent scopes and need to be taken from elsewhere.
+    invocation_parent_scopes: FxHashMap<ExpnId, ParentScope<'a>>,
+    /// Legacy scopes *produced* by expanding the macro invocations,
+    /// include all the `macro_rules` items and other invocations generated by them.
+    output_legacy_scopes: FxHashMap<ExpnId, LegacyScope<'a>>,
 
     /// Avoid duplicated errors for "name already defined".
     name_already_seen: FxHashMap<Name, Span>,
@@ -936,7 +939,6 @@ pub struct ResolverArenas<'a> {
     name_bindings: arena::TypedArena<NameBinding<'a>>,
     import_directives: arena::TypedArena<ImportDirective<'a>>,
     name_resolutions: arena::TypedArena<RefCell<NameResolution<'a>>>,
-    invocation_data: arena::TypedArena<InvocationData<'a>>,
     legacy_bindings: arena::TypedArena<LegacyBinding<'a>>,
 }
 
@@ -961,10 +963,6 @@ impl<'a> ResolverArenas<'a> {
     fn alloc_name_resolution(&'a self) -> &'a RefCell<NameResolution<'a>> {
         self.name_resolutions.alloc(Default::default())
     }
-    fn alloc_invocation_data(&'a self, expansion_data: InvocationData<'a>)
-                             -> &'a InvocationData<'a> {
-        self.invocation_data.alloc(expansion_data)
-    }
     fn alloc_legacy_binding(&'a self, binding: LegacyBinding<'a>) -> &'a LegacyBinding<'a> {
         self.legacy_bindings.alloc(binding)
     }
@@ -1078,9 +1076,8 @@ impl<'a> Resolver<'a> {
             }
         }
 
-        let mut invocations = FxHashMap::default();
-        invocations.insert(ExpnId::root(),
-                           arenas.alloc_invocation_data(InvocationData::default(graph_root)));
+        let mut invocation_parent_scopes = FxHashMap::default();
+        invocation_parent_scopes.insert(ExpnId::root(), ParentScope::default(graph_root));
 
         let mut macro_defs = FxHashMap::default();
         macro_defs.insert(ExpnId::root(), root_def_id);
@@ -1152,7 +1149,8 @@ impl<'a> Resolver<'a> {
             dummy_ext_bang: Lrc::new(SyntaxExtension::dummy_bang(session.edition())),
             dummy_ext_derive: Lrc::new(SyntaxExtension::dummy_derive(session.edition())),
             non_macro_attrs: [non_macro_attr(false), non_macro_attr(true)],
-            invocations,
+            invocation_parent_scopes,
+            output_legacy_scopes: Default::default(),
             macro_defs,
             local_macro_def_scopes: FxHashMap::default(),
             name_already_seen: FxHashMap::default(),
@@ -1370,8 +1368,9 @@ impl<'a> Resolver<'a> {
                     LegacyScope::Binding(binding) => Scope::MacroRules(
                         binding.parent_legacy_scope
                     ),
-                    LegacyScope::Invocation(invoc) => Scope::MacroRules(
-                        invoc.output_legacy_scope.get().unwrap_or(invoc.parent_legacy_scope)
+                    LegacyScope::Invocation(invoc_id) => Scope::MacroRules(
+                        self.output_legacy_scopes.get(&invoc_id).cloned()
+                            .unwrap_or(self.invocation_parent_scopes[&invoc_id].legacy)
                     ),
                     LegacyScope::Empty => Scope::Module(module),
                 }
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 754983e3bd42c..e64ca61b7efdc 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -1,6 +1,6 @@
 use crate::{AmbiguityError, AmbiguityKind, AmbiguityErrorMisc, Determinacy};
 use crate::{CrateLint, Resolver, ResolutionError, Scope, ScopeSet, ParentScope, Weak};
-use crate::{Module, ModuleKind, NameBinding, PathResult, Segment, ToNameBinding};
+use crate::{ModuleKind, NameBinding, PathResult, Segment, ToNameBinding};
 use crate::{ModuleOrUniformRoot, KNOWN_TOOLS};
 use crate::Namespace::*;
 use crate::build_reduced_graph::BuildReducedGraphVisitor;
@@ -22,36 +22,11 @@ use syntax::feature_gate::GateIssue;
 use syntax::symbol::{Symbol, kw, sym};
 use syntax_pos::{Span, DUMMY_SP};
 
-use std::cell::Cell;
 use std::{mem, ptr};
 use rustc_data_structures::sync::Lrc;
 
 type Res = def::Res<ast::NodeId>;
 
-// FIXME: Merge this with `ParentScope`.
-#[derive(Clone, Debug)]
-pub struct InvocationData<'a> {
-    /// The module in which the macro was invoked.
-    crate module: Module<'a>,
-    /// The legacy scope in which the macro was invoked.
-    /// The invocation path is resolved in this scope.
-    crate parent_legacy_scope: LegacyScope<'a>,
-    /// The legacy scope *produced* by expanding this macro invocation,
-    /// includes all the macro_rules items, other invocations, etc generated by it.
-    /// `None` if the macro is not expanded yet.
-    crate output_legacy_scope: Cell<Option<LegacyScope<'a>>>,
-}
-
-impl<'a> InvocationData<'a> {
-    pub fn default(module: Module<'a>) -> Self {
-        InvocationData {
-            module,
-            parent_legacy_scope: LegacyScope::Empty,
-            output_legacy_scope: Cell::new(None),
-        }
-    }
-}
-
 /// Binding produced by a `macro_rules` item.
 /// Not modularized, can shadow previous legacy bindings, etc.
 #[derive(Debug)]
@@ -75,7 +50,7 @@ pub enum LegacyScope<'a> {
     Binding(&'a LegacyBinding<'a>),
     /// The scope introduced by a macro invocation that can potentially
     /// create a `macro_rules!` macro definition.
-    Invocation(&'a InvocationData<'a>),
+    Invocation(ExpnId),
 }
 
 // Macro namespace is separated into two sub-namespaces, one for bang macros and
@@ -124,9 +99,8 @@ impl<'a> base::Resolver for Resolver<'a> {
             ExpnKind::Macro(MacroKind::Attr, sym::test_case), DUMMY_SP, self.session.edition()
         )));
         let module = self.module_map[&self.definitions.local_def_id(id)];
-        let invocation_data = self.arenas.alloc_invocation_data(InvocationData::default(module));
+        self.invocation_parent_scopes.insert(expn_id, ParentScope::default(module));
         self.definitions.set_invocation_parent(expn_id, module.def_id().unwrap().index);
-        self.invocations.insert(expn_id, invocation_data);
         expn_id
     }
 
@@ -140,29 +114,29 @@ impl<'a> base::Resolver for Resolver<'a> {
         });
     }
 
-    fn visit_ast_fragment_with_placeholders(&mut self, expn_id: ExpnId, fragment: &AstFragment,
-                                            derives: &[ExpnId]) {
-        fragment.visit_with(&mut DefCollector::new(&mut self.definitions, expn_id));
-
-        let invocation = self.invocations[&expn_id];
-        invocation.module.unresolved_invocations.borrow_mut().remove(&expn_id);
-        invocation.module.unresolved_invocations.borrow_mut().extend(derives);
-        let parent_def = self.definitions.invocation_parent(expn_id);
+    fn visit_ast_fragment_with_placeholders(
+        &mut self, expansion: ExpnId, fragment: &AstFragment, derives: &[ExpnId]
+    ) {
+        // Fill in some data for derives if the fragment is from a derive container.
+        let parent_scope = self.invocation_parent_scopes[&expansion].clone();
+        let parent_def = self.definitions.invocation_parent(expansion);
+        self.invocation_parent_scopes.extend(
+            derives.iter().map(|&derive| (derive, parent_scope.clone()))
+        );
         for &derive_invoc_id in derives {
             self.definitions.set_invocation_parent(derive_invoc_id, parent_def);
         }
-        self.invocations.extend(derives.iter().map(|&derive| (derive, invocation)));
-        let mut visitor = BuildReducedGraphVisitor {
-            r: self,
-            parent_scope: ParentScope {
-                module: invocation.module,
-                expansion: expn_id,
-                legacy: invocation.parent_legacy_scope,
-                derives: Vec::new(),
-            },
-        };
+        parent_scope.module.unresolved_invocations.borrow_mut().remove(&expansion);
+        parent_scope.module.unresolved_invocations.borrow_mut().extend(derives);
+
+        // Integrate the new AST fragment into all the definition and module structures.
+        // We are inside the `expansion` new, but other parent scope components are still the same.
+        fragment.visit_with(&mut DefCollector::new(&mut self.definitions, expansion));
+        let parent_scope = ParentScope { expansion, ..parent_scope };
+        let mut visitor = BuildReducedGraphVisitor { r: self, parent_scope };
         fragment.visit_with(&mut visitor);
-        invocation.output_legacy_scope.set(Some(visitor.parent_scope.legacy));
+        let output_legacy_scope = visitor.parent_scope.legacy;
+        self.output_legacy_scopes.insert(expansion, output_legacy_scope);
     }
 
     fn register_builtin_macro(&mut self, ident: ast::Ident, ext: SyntaxExtension) {
@@ -178,7 +152,8 @@ impl<'a> base::Resolver for Resolver<'a> {
 
     fn resolve_macro_invocation(&mut self, invoc: &Invocation, invoc_id: ExpnId, force: bool)
                                 -> Result<Option<Lrc<SyntaxExtension>>, Indeterminate> {
-        let (path, kind, derives_in_scope, after_derive) = match invoc.kind {
+        let parent_scope = &self.invocation_parent_scopes[&invoc_id].clone();
+        let (path, kind, derives, after_derive) = match invoc.kind {
             InvocationKind::Attr { ref attr, ref derives, after_derive, .. } =>
                 (&attr.path, MacroKind::Attr, derives.clone(), after_derive),
             InvocationKind::Bang { ref mac, .. } =>
@@ -192,7 +167,6 @@ impl<'a> base::Resolver for Resolver<'a> {
                 // will automatically knows about itself.
                 let mut result = Ok(None);
                 if derives.len() > 1 {
-                    let parent_scope = &self.invoc_parent_scope(invoc_id, Vec::new());
                     for path in derives {
                         match self.resolve_macro_path(path, Some(MacroKind::Derive),
                                                       parent_scope, true, force) {
@@ -209,7 +183,8 @@ impl<'a> base::Resolver for Resolver<'a> {
             }
         };
 
-        let parent_scope = &self.invoc_parent_scope(invoc_id, derives_in_scope);
+        // Derives are not included when `invocations` are collected, so we have to add them here.
+        let parent_scope = &ParentScope { derives, ..parent_scope.clone() };
         let (ext, res) = self.smart_resolve_macro_path(path, kind, parent_scope, force)?;
 
         let span = invoc.span();
@@ -247,16 +222,6 @@ impl<'a> base::Resolver for Resolver<'a> {
 }
 
 impl<'a> Resolver<'a> {
-    fn invoc_parent_scope(&self, invoc_id: ExpnId, derives: Vec<ast::Path>) -> ParentScope<'a> {
-        let invoc = self.invocations[&invoc_id];
-        ParentScope {
-            module: invoc.module,
-            expansion: invoc_id.parent(),
-            legacy: invoc.parent_legacy_scope,
-            derives,
-        }
-    }
-
     /// Resolve macro path with error reporting and recovery.
     fn smart_resolve_macro_path(
         &mut self,
@@ -466,8 +431,9 @@ impl<'a> Resolver<'a> {
                 Scope::MacroRules(legacy_scope) => match legacy_scope {
                     LegacyScope::Binding(legacy_binding) if ident == legacy_binding.ident =>
                         Ok((legacy_binding.binding, Flags::MACRO_RULES)),
-                    LegacyScope::Invocation(invoc) if invoc.output_legacy_scope.get().is_none() =>
-                        Err(Determinacy::Undetermined),
+                    LegacyScope::Invocation(invoc_id)
+                        if !this.output_legacy_scopes.contains_key(&invoc_id) =>
+                            Err(Determinacy::Undetermined),
                     _ => Err(Determinacy::Determined),
                 }
                 Scope::CrateRoot => {

From ea68bc85e01c17bdef5a593188d7a185c6014302 Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Tue, 13 Aug 2019 01:39:10 +0300
Subject: [PATCH 26/35] resolve: Make `ParentScope` `Copy`

By allocating its derive paths on the resolver arena.
---
 src/librustc_resolve/build_reduced_graph.rs | 17 ++++++-------
 src/librustc_resolve/diagnostics.rs         |  4 +--
 src/librustc_resolve/lib.rs                 | 14 +++++++----
 src/librustc_resolve/macros.rs              | 28 ++++++++++-----------
 src/librustc_resolve/resolve_imports.rs     |  2 +-
 5 files changed, 32 insertions(+), 33 deletions(-)

diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 51a0a74568851..bfb7844b543c1 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -300,10 +300,9 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
         root_id: NodeId,
         vis: ty::Visibility,
     ) {
-        let parent_scope = &self.parent_scope;
-        let current_module = parent_scope.module;
+        let current_module = self.parent_scope.module;
         let directive = self.r.arenas.alloc_import_directive(ImportDirective {
-            parent_scope: parent_scope.clone(),
+            parent_scope: self.parent_scope,
             module_path,
             imported_module: Cell::new(None),
             subclass,
@@ -601,7 +600,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                 let directive = self.r.arenas.alloc_import_directive(ImportDirective {
                     root_id: item.id,
                     id: item.id,
-                    parent_scope: self.parent_scope.clone(),
+                    parent_scope: self.parent_scope,
                     imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))),
                     subclass: ImportDirectiveSubclass::ExternCrate {
                         source: orig_name,
@@ -994,7 +993,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                 |this: &Self, span| this.r.arenas.alloc_import_directive(ImportDirective {
             root_id: item.id,
             id: item.id,
-            parent_scope: this.parent_scope.clone(),
+            parent_scope: this.parent_scope,
             imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))),
             subclass: ImportDirectiveSubclass::MacroUse,
             use_span_with_attributes: item.span_with_attributes(),
@@ -1066,11 +1065,9 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
     fn visit_invoc(&mut self, id: ast::NodeId) -> LegacyScope<'a> {
         let invoc_id = id.placeholder_to_expn_id();
 
-        let parent_scope = self.parent_scope.clone();
-        parent_scope.module.unresolved_invocations.borrow_mut().insert(invoc_id);
+        self.parent_scope.module.unresolved_invocations.borrow_mut().insert(invoc_id);
 
-        let old_parent_scope =
-            self.r.invocation_parent_scopes.insert(invoc_id, parent_scope.clone());
+        let old_parent_scope = self.r.invocation_parent_scopes.insert(invoc_id, self.parent_scope);
         assert!(old_parent_scope.is_none(), "invocation data is reset for an invocation");
 
         LegacyScope::Invocation(invoc_id)
@@ -1261,7 +1258,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
 
     fn visit_attribute(&mut self, attr: &'b ast::Attribute) {
         if !attr.is_sugared_doc && is_builtin_attr(attr) {
-            self.r.builtin_attrs.push((attr.path.segments[0].ident, self.parent_scope.clone()));
+            self.r.builtin_attrs.push((attr.path.segments[0].ident, self.parent_scope));
         }
         visit::walk_attribute(self, attr);
     }
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index f824dfe8e7812..8ec5d64ef3d09 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -376,9 +376,9 @@ impl<'a> Resolver<'a> {
                 Scope::DeriveHelpers => {
                     let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
                     if filter_fn(res) {
-                        for derive in &parent_scope.derives {
+                        for derive in parent_scope.derives {
                             let parent_scope =
-                                &ParentScope { derives: Vec::new(), ..*parent_scope };
+                                &ParentScope { derives: &[], ..*parent_scope };
                             if let Ok((Some(ext), _)) = this.resolve_macro_path(
                                 derive, Some(MacroKind::Derive), parent_scope, false, false
                             ) {
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 85f8d07bf9bd5..b0944b480a2d0 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -122,12 +122,12 @@ enum ScopeSet {
 /// Serves as a starting point for the scope visitor.
 /// This struct is currently used only for early resolution (imports and macros),
 /// but not for late resolution yet.
-#[derive(Clone, Debug)]
+#[derive(Clone, Copy, Debug)]
 pub struct ParentScope<'a> {
     module: Module<'a>,
     expansion: ExpnId,
     legacy: LegacyScope<'a>,
-    derives: Vec<ast::Path>,
+    derives: &'a [ast::Path],
 }
 
 impl<'a> ParentScope<'a> {
@@ -136,7 +136,7 @@ impl<'a> ParentScope<'a> {
             module,
             expansion: ExpnId::root(),
             legacy: LegacyScope::Empty,
-            derives: Vec::new(),
+            derives: &[],
         }
     }
 }
@@ -940,6 +940,7 @@ pub struct ResolverArenas<'a> {
     import_directives: arena::TypedArena<ImportDirective<'a>>,
     name_resolutions: arena::TypedArena<RefCell<NameResolution<'a>>>,
     legacy_bindings: arena::TypedArena<LegacyBinding<'a>>,
+    ast_paths: arena::TypedArena<ast::Path>,
 }
 
 impl<'a> ResolverArenas<'a> {
@@ -966,6 +967,9 @@ impl<'a> ResolverArenas<'a> {
     fn alloc_legacy_binding(&'a self, binding: LegacyBinding<'a>) -> &'a LegacyBinding<'a> {
         self.legacy_bindings.alloc(binding)
     }
+    fn alloc_ast_paths(&'a self, paths: &[ast::Path]) -> &'a [ast::Path] {
+        self.ast_paths.alloc_from_iter(paths.iter().cloned())
+    }
 }
 
 impl<'a, 'b> ty::DefIdTree for &'a Resolver<'b> {
@@ -1515,7 +1519,7 @@ impl<'a> Resolver<'a> {
                 self.hygienic_lexical_parent(module, &mut ident.span)
             };
             module = unwrap_or!(opt_module, break);
-            let adjusted_parent_scope = &ParentScope { module, ..parent_scope.clone() };
+            let adjusted_parent_scope = &ParentScope { module, ..*parent_scope };
             let result = self.resolve_ident_in_module_unadjusted(
                 ModuleOrUniformRoot::Module(module),
                 ident,
@@ -1651,7 +1655,7 @@ impl<'a> Resolver<'a> {
             ModuleOrUniformRoot::Module(m) => {
                 if let Some(def) = ident.span.modernize_and_adjust(m.expansion) {
                     tmp_parent_scope =
-                        ParentScope { module: self.macro_def_scope(def), ..parent_scope.clone() };
+                        ParentScope { module: self.macro_def_scope(def), ..*parent_scope };
                     adjusted_parent_scope = &tmp_parent_scope;
                 }
             }
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index e64ca61b7efdc..dd8e340703115 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -118,11 +118,9 @@ impl<'a> base::Resolver for Resolver<'a> {
         &mut self, expansion: ExpnId, fragment: &AstFragment, derives: &[ExpnId]
     ) {
         // Fill in some data for derives if the fragment is from a derive container.
-        let parent_scope = self.invocation_parent_scopes[&expansion].clone();
+        let parent_scope = self.invocation_parent_scopes[&expansion];
         let parent_def = self.definitions.invocation_parent(expansion);
-        self.invocation_parent_scopes.extend(
-            derives.iter().map(|&derive| (derive, parent_scope.clone()))
-        );
+        self.invocation_parent_scopes.extend(derives.iter().map(|&derive| (derive, parent_scope)));
         for &derive_invoc_id in derives {
             self.definitions.set_invocation_parent(derive_invoc_id, parent_def);
         }
@@ -152,14 +150,14 @@ impl<'a> base::Resolver for Resolver<'a> {
 
     fn resolve_macro_invocation(&mut self, invoc: &Invocation, invoc_id: ExpnId, force: bool)
                                 -> Result<Option<Lrc<SyntaxExtension>>, Indeterminate> {
-        let parent_scope = &self.invocation_parent_scopes[&invoc_id].clone();
+        let parent_scope = self.invocation_parent_scopes[&invoc_id];
         let (path, kind, derives, after_derive) = match invoc.kind {
             InvocationKind::Attr { ref attr, ref derives, after_derive, .. } =>
-                (&attr.path, MacroKind::Attr, derives.clone(), after_derive),
+                (&attr.path, MacroKind::Attr, self.arenas.alloc_ast_paths(derives), after_derive),
             InvocationKind::Bang { ref mac, .. } =>
-                (&mac.path, MacroKind::Bang, Vec::new(), false),
+                (&mac.path, MacroKind::Bang, &[][..], false),
             InvocationKind::Derive { ref path, .. } =>
-                (path, MacroKind::Derive, Vec::new(), false),
+                (path, MacroKind::Derive, &[][..], false),
             InvocationKind::DeriveContainer { ref derives, .. } => {
                 // Block expansion of derives in the container until we know whether one of them
                 // is a built-in `Copy`. Skip the resolution if there's only one derive - either
@@ -169,7 +167,7 @@ impl<'a> base::Resolver for Resolver<'a> {
                 if derives.len() > 1 {
                     for path in derives {
                         match self.resolve_macro_path(path, Some(MacroKind::Derive),
-                                                      parent_scope, true, force) {
+                                                      &parent_scope, true, force) {
                             Ok((Some(ref ext), _)) if ext.is_derive_copy => {
                                 self.add_derives(invoc.expansion_data.id, SpecialDerives::COPY);
                                 return Ok(None);
@@ -184,7 +182,7 @@ impl<'a> base::Resolver for Resolver<'a> {
         };
 
         // Derives are not included when `invocations` are collected, so we have to add them here.
-        let parent_scope = &ParentScope { derives, ..parent_scope.clone() };
+        let parent_scope = &ParentScope { derives, ..parent_scope };
         let (ext, res) = self.smart_resolve_macro_path(path, kind, parent_scope, force)?;
 
         let span = invoc.span();
@@ -324,7 +322,7 @@ impl<'a> Resolver<'a> {
             if trace {
                 let kind = kind.expect("macro kind must be specified if tracing is enabled");
                 self.multi_segment_macro_resolutions
-                    .push((path, path_span, kind, parent_scope.clone(), res.ok()));
+                    .push((path, path_span, kind, *parent_scope, res.ok()));
             }
 
             self.prohibit_imported_non_macro_attrs(None, res.ok(), path_span);
@@ -341,7 +339,7 @@ impl<'a> Resolver<'a> {
             if trace {
                 let kind = kind.expect("macro kind must be specified if tracing is enabled");
                 self.single_segment_macro_resolutions
-                    .push((path[0].ident, kind, parent_scope.clone(), binding.ok()));
+                    .push((path[0].ident, kind, *parent_scope, binding.ok()));
             }
 
             let res = binding.map(|binding| binding.res());
@@ -410,8 +408,8 @@ impl<'a> Resolver<'a> {
             let result = match scope {
                 Scope::DeriveHelpers => {
                     let mut result = Err(Determinacy::Determined);
-                    for derive in &parent_scope.derives {
-                        let parent_scope = &ParentScope { derives: Vec::new(), ..*parent_scope };
+                    for derive in parent_scope.derives {
+                        let parent_scope = &ParentScope { derives: &[], ..*parent_scope };
                         match this.resolve_macro_path(derive, Some(MacroKind::Derive),
                                                       parent_scope, true, force) {
                             Ok((Some(ext), _)) => if ext.helper_attrs.contains(&ident.name) {
@@ -457,7 +455,7 @@ impl<'a> Resolver<'a> {
                     }
                 }
                 Scope::Module(module) => {
-                    let adjusted_parent_scope = &ParentScope { module, ..parent_scope.clone() };
+                    let adjusted_parent_scope = &ParentScope { module, ..*parent_scope };
                     let binding = this.resolve_ident_in_module_unadjusted_ext(
                         ModuleOrUniformRoot::Module(module),
                         ident,
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index ef8fcc9ba8a55..0e3bdc1274a68 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -394,7 +394,7 @@ impl<'a> Resolver<'a> {
             match ident.span.glob_adjust(module.expansion, glob_import.span) {
                 Some(Some(def)) => {
                     tmp_parent_scope =
-                        ParentScope { module: self.macro_def_scope(def), ..parent_scope.clone() };
+                        ParentScope { module: self.macro_def_scope(def), ..*parent_scope };
                     adjusted_parent_scope = &tmp_parent_scope;
                 }
                 Some(None) => {}

From 310ee4d98c9a421487914d12474f121a75197bf2 Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Tue, 13 Aug 2019 02:13:36 +0300
Subject: [PATCH 27/35] resolve: Privatize `BuildReducedGraphVisitor`

---
 src/librustc_resolve/build_reduced_graph.rs | 27 ++++++++++++++-------
 src/librustc_resolve/diagnostics.rs         |  2 +-
 src/librustc_resolve/lib.rs                 |  5 ++--
 src/librustc_resolve/macros.rs              |  7 ++----
 4 files changed, 23 insertions(+), 18 deletions(-)

diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index bfb7844b543c1..d8799f8332f42 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -30,6 +30,7 @@ use syntax::attr;
 use syntax::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind, NodeId};
 use syntax::ast::{MetaItemKind, StmtKind, TraitItem, TraitItemKind, Variant};
 use syntax::ext::base::{MacroKind, SyntaxExtension};
+use syntax::ext::expand::AstFragment;
 use syntax::ext::hygiene::ExpnId;
 use syntax::feature_gate::is_builtin_attr;
 use syntax::parse::token::{self, Token};
@@ -67,7 +68,7 @@ impl<'a> ToNameBinding<'a> for (Res, ty::Visibility, Span, ExpnId) {
     }
 }
 
-pub(crate) struct IsMacroExport;
+struct IsMacroExport;
 
 impl<'a> ToNameBinding<'a> for (Res, ty::Visibility, Span, ExpnId, IsMacroExport) {
     fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> {
@@ -84,7 +85,7 @@ impl<'a> ToNameBinding<'a> for (Res, ty::Visibility, Span, ExpnId, IsMacroExport
 impl<'a> Resolver<'a> {
     /// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined;
     /// otherwise, reports an error.
-    pub fn define<T>(&mut self, parent: Module<'a>, ident: Ident, ns: Namespace, def: T)
+    crate fn define<T>(&mut self, parent: Module<'a>, ident: Ident, ns: Namespace, def: T)
         where T: ToNameBinding<'a>,
     {
         let binding = def.to_name_binding(self.arenas);
@@ -93,7 +94,7 @@ impl<'a> Resolver<'a> {
         }
     }
 
-    pub fn get_module(&mut self, def_id: DefId) -> Module<'a> {
+    crate fn get_module(&mut self, def_id: DefId) -> Module<'a> {
         if def_id.krate == LOCAL_CRATE {
             return self.module_map[&def_id]
         }
@@ -119,7 +120,7 @@ impl<'a> Resolver<'a> {
         module
     }
 
-    pub fn macro_def_scope(&mut self, expn_id: ExpnId) -> Module<'a> {
+    crate fn macro_def_scope(&mut self, expn_id: ExpnId) -> Module<'a> {
         let def_id = match self.macro_defs.get(&expn_id) {
             Some(def_id) => *def_id,
             None => return self.graph_root,
@@ -141,7 +142,7 @@ impl<'a> Resolver<'a> {
         }
     }
 
-    crate fn get_macro_by_def_id(&mut self, def_id: DefId) -> Option<Lrc<SyntaxExtension>> {
+    fn get_macro_by_def_id(&mut self, def_id: DefId) -> Option<Lrc<SyntaxExtension>> {
         if let Some(ext) = self.macro_map.get(&def_id) {
             return Some(ext.clone());
         }
@@ -158,7 +159,7 @@ impl<'a> Resolver<'a> {
 
     /// Ensures that the reduced graph rooted at the given external module
     /// is built, building it if it is not.
-    pub fn populate_module_if_necessary(&mut self, module: Module<'a>) {
+    crate fn populate_module_if_necessary(&mut self, module: Module<'a>) {
         if module.populated.get() { return }
         let def_id = module.def_id().unwrap();
         for child in self.cstore.item_children_untracked(def_id, self.session) {
@@ -168,11 +169,19 @@ impl<'a> Resolver<'a> {
         }
         module.populated.set(true)
     }
+
+    crate fn build_reduced_graph(
+        &mut self, fragment: &AstFragment, parent_scope: ParentScope<'a>
+    ) -> LegacyScope<'a> {
+        let mut visitor = BuildReducedGraphVisitor { r: self, parent_scope };
+        fragment.visit_with(&mut visitor);
+        visitor.parent_scope.legacy
+    }
 }
 
-pub struct BuildReducedGraphVisitor<'a, 'b> {
-    pub r: &'b mut Resolver<'a>,
-    pub parent_scope: ParentScope<'a>,
+struct BuildReducedGraphVisitor<'a, 'b> {
+    r: &'b mut Resolver<'a>,
+    parent_scope: ParentScope<'a>,
 }
 
 impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index 8ec5d64ef3d09..861b0fd44ac41 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -455,7 +455,7 @@ impl<'a> Resolver<'a> {
                         let mut tmp_suggestions = Vec::new();
                         add_module_candidates(prelude, &mut tmp_suggestions, filter_fn);
                         suggestions.extend(tmp_suggestions.into_iter().filter(|s| {
-                            use_prelude || this.is_builtin_macro(s.res.opt_def_id())
+                            use_prelude || this.is_builtin_macro(s.res)
                         }));
                     }
                 }
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index b0944b480a2d0..0cf9aa72d7834 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -1196,9 +1196,8 @@ impl<'a> Resolver<'a> {
         f(self, MacroNS);
     }
 
-    fn is_builtin_macro(&mut self, def_id: Option<DefId>) -> bool {
-        def_id.and_then(|def_id| self.get_macro_by_def_id(def_id))
-              .map_or(false, |ext| ext.is_builtin)
+    fn is_builtin_macro(&mut self, res: Res) -> bool {
+        self.get_macro(res).map_or(false, |ext| ext.is_builtin)
     }
 
     fn macro_def(&self, mut ctxt: SyntaxContext) -> DefId {
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index dd8e340703115..0a63dd2558d35 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -3,7 +3,6 @@ use crate::{CrateLint, Resolver, ResolutionError, Scope, ScopeSet, ParentScope,
 use crate::{ModuleKind, NameBinding, PathResult, Segment, ToNameBinding};
 use crate::{ModuleOrUniformRoot, KNOWN_TOOLS};
 use crate::Namespace::*;
-use crate::build_reduced_graph::BuildReducedGraphVisitor;
 use crate::resolve_imports::ImportResolver;
 use rustc::hir::def::{self, DefKind, NonMacroAttrKind};
 use rustc::hir::map::DefCollector;
@@ -131,9 +130,7 @@ impl<'a> base::Resolver for Resolver<'a> {
         // We are inside the `expansion` new, but other parent scope components are still the same.
         fragment.visit_with(&mut DefCollector::new(&mut self.definitions, expansion));
         let parent_scope = ParentScope { expansion, ..parent_scope };
-        let mut visitor = BuildReducedGraphVisitor { r: self, parent_scope };
-        fragment.visit_with(&mut visitor);
-        let output_legacy_scope = visitor.parent_scope.legacy;
+        let output_legacy_scope = self.build_reduced_graph(fragment, parent_scope);
         self.output_legacy_scopes.insert(expansion, output_legacy_scope);
     }
 
@@ -530,7 +527,7 @@ impl<'a> Resolver<'a> {
                             false,
                             path_span,
                         ) {
-                            if use_prelude || this.is_builtin_macro(binding.res().opt_def_id()) {
+                            if use_prelude || this.is_builtin_macro(binding.res()) {
                                 result = Ok((binding, Flags::PRELUDE | Flags::MISC_FROM_PRELUDE));
                             }
                         }

From aca1353240e03eaba4b3540e1c7b3dea99d5c8ac Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Tue, 13 Aug 2019 02:46:42 +0300
Subject: [PATCH 28/35] resolve: Add some comments to the main modules

---
 src/librustc_resolve/build_reduced_graph.rs | 8 +++++---
 src/librustc_resolve/late.rs                | 7 +++++++
 src/librustc_resolve/lib.rs                 | 9 +++++++++
 src/librustc_resolve/macros.rs              | 3 +++
 src/librustc_resolve/resolve_imports.rs     | 2 ++
 5 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index d8799f8332f42..c42a933a954a9 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -1,7 +1,9 @@
-//! Reduced graph building.
+//! After we obtain a fresh AST fragment from a macro, code in this module helps to integrate
+//! that fragment into the module structures that are already partially built.
 //!
-//! Here we build the "reduced graph": the graph of the module tree without
-//! any imports resolved.
+//! Items from the fragment are placed into modules,
+//! unexpanded macros in the fragment are visited and registered.
+//! Imports are also considered items and placed into modules here, but not resolved yet.
 
 use crate::macros::{LegacyBinding, LegacyScope};
 use crate::resolve_imports::ImportDirective;
diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index fbd9f1d48e5e6..d97ee61d839a2 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -1,3 +1,10 @@
+//! "Late resolution" is the pass that resolves most of names in a crate beside imports and macros.
+//! It runs when the crate is fully expanded and its module structure is fully built.
+//! So it just walks through the crate and resolves all the expressions, types, etc.
+//!
+//! If you wonder why there's no `early.rs`, that's because it's split into three files -
+//! `build_reduced_graph.rs`, `macros.rs` and `resolve_imports.rs`.
+
 use GenericParameters::*;
 use RibKind::*;
 
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 0cf9aa72d7834..2b55f9dc79d08 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -1,3 +1,12 @@
+//! This crate is responsible for the part of name resolution that doesn't require type checker.
+//!
+//! Module structure of the crate is built here.
+//! Paths in macros, imports, expressions, types, patterns are resolved here.
+//! Label names are resolved here as well.
+//!
+//! Type-relative name resolution (methods, fields, associated items) happens in `librustc_typeck`.
+//! Lifetime names are resolved in `librustc/middle/resolve_lifetime.rs`.
+
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
 
 #![feature(crate_visibility_modifier)]
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 0a63dd2558d35..2f9bee7490813 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -1,3 +1,6 @@
+//! A bunch of methods and structures more or less related to resolving macros and
+//! interface provided by `Resolver` to macro expander.
+
 use crate::{AmbiguityError, AmbiguityKind, AmbiguityErrorMisc, Determinacy};
 use crate::{CrateLint, Resolver, ResolutionError, Scope, ScopeSet, ParentScope, Weak};
 use crate::{ModuleKind, NameBinding, PathResult, Segment, ToNameBinding};
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index 0e3bdc1274a68..693893e9ef13b 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -1,3 +1,5 @@
+//! A bunch of methods and structures more or less related to resolving imports.
+
 use ImportDirectiveSubclass::*;
 
 use crate::{AmbiguityError, AmbiguityKind, AmbiguityErrorMisc};

From 1a447738b8a7ac8f0a47a134f9fa1a60a4621620 Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Tue, 13 Aug 2019 03:34:46 +0300
Subject: [PATCH 29/35] hygiene: Merge `ExpnInfo` and `InternalExpnData`

---
 src/librustc/hir/lowering.rs                  |  2 +-
 src/librustc/ich/impls_syntax.rs              |  3 +-
 src/librustc/ty/query/on_disk_cache.rs        |  4 +-
 src/librustc_resolve/macros.rs                | 11 +--
 src/libsyntax/ext/base.rs                     |  5 +-
 src/libsyntax/ext/expand.rs                   | 15 ++--
 src/libsyntax_ext/deriving/clone.rs           |  2 +-
 src/libsyntax_ext/deriving/cmp/eq.rs          |  2 +-
 src/libsyntax_ext/deriving/cmp/partial_eq.rs  |  2 +-
 src/libsyntax_ext/deriving/generic/mod.rs     |  2 +-
 src/libsyntax_ext/plugin_macro_defs.rs        |  4 +-
 src/libsyntax_ext/proc_macro_harness.rs       |  3 +-
 src/libsyntax_ext/standard_library_imports.rs |  4 +-
 src/libsyntax_ext/test_harness.rs             |  5 +-
 src/libsyntax_pos/hygiene.rs                  | 70 +++++++++----------
 15 files changed, 67 insertions(+), 67 deletions(-)

diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index f942a0fb85792..0b7dacf8383e8 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -704,7 +704,7 @@ impl<'a> LoweringContext<'a> {
         span: Span,
         allow_internal_unstable: Option<Lrc<[Symbol]>>,
     ) -> Span {
-        span.fresh_expansion(ExpnId::root(), ExpnInfo {
+        span.fresh_expansion(ExpnInfo {
             def_site: span,
             allow_internal_unstable,
             ..ExpnInfo::default(ExpnKind::Desugaring(reason), span, self.sess.edition())
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
index 5cc8324b31606..22e2cff359520 100644
--- a/src/librustc/ich/impls_syntax.rs
+++ b/src/librustc/ich/impls_syntax.rs
@@ -398,8 +398,9 @@ impl_stable_hash_for!(enum ::syntax_pos::hygiene::Transparency {
 });
 
 impl_stable_hash_for!(struct ::syntax_pos::hygiene::ExpnInfo {
-    call_site,
     kind,
+    parent -> _,
+    call_site,
     def_site,
     default_transparency,
     allow_internal_unstable,
diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs
index 2286271b9eb4f..351b9988bb25c 100644
--- a/src/librustc/ty/query/on_disk_cache.rs
+++ b/src/librustc/ty/query/on_disk_cache.rs
@@ -588,13 +588,13 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx> {
 
         let expn_info_tag = u8::decode(self)?;
 
-        // FIXME(mw): This method does not restore `InternalExpnData::parent` or
+        // FIXME(mw): This method does not restore `ExpnInfo::parent` or
         // `SyntaxContextData::prev_ctxt` or `SyntaxContextData::opaque`. These things
         // don't seem to be used after HIR lowering, so everything should be fine
         // as long as incremental compilation does not kick in before that.
         let location = || Span::with_root_ctxt(lo, hi);
         let recover_from_expn_info = |this: &Self, expn_info, pos| {
-            let span = location().fresh_expansion(ExpnId::root(), expn_info);
+            let span = location().fresh_expansion(expn_info);
             this.synthetic_expansion_infos.borrow_mut().insert(pos, span.ctxt());
             span
         };
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 2f9bee7490813..58e785ab8c253 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -97,7 +97,7 @@ impl<'a> base::Resolver for Resolver<'a> {
     }
 
     fn get_module_scope(&mut self, id: ast::NodeId) -> ExpnId {
-        let expn_id = ExpnId::fresh(ExpnId::root(), Some(ExpnInfo::default(
+        let expn_id = ExpnId::fresh(Some(ExpnInfo::default(
             ExpnKind::Macro(MacroKind::Attr, sym::test_case), DUMMY_SP, self.session.edition()
         )));
         let module = self.module_map[&self.definitions.local_def_id(id)];
@@ -120,7 +120,8 @@ impl<'a> base::Resolver for Resolver<'a> {
         &mut self, expansion: ExpnId, fragment: &AstFragment, derives: &[ExpnId]
     ) {
         // Fill in some data for derives if the fragment is from a derive container.
-        let parent_scope = self.invocation_parent_scopes[&expansion];
+        // We are inside the `expansion` now, but other parent scope components are still the same.
+        let parent_scope = ParentScope { expansion, ..self.invocation_parent_scopes[&expansion] };
         let parent_def = self.definitions.invocation_parent(expansion);
         self.invocation_parent_scopes.extend(derives.iter().map(|&derive| (derive, parent_scope)));
         for &derive_invoc_id in derives {
@@ -130,9 +131,7 @@ impl<'a> base::Resolver for Resolver<'a> {
         parent_scope.module.unresolved_invocations.borrow_mut().extend(derives);
 
         // Integrate the new AST fragment into all the definition and module structures.
-        // We are inside the `expansion` new, but other parent scope components are still the same.
         fragment.visit_with(&mut DefCollector::new(&mut self.definitions, expansion));
-        let parent_scope = ParentScope { expansion, ..parent_scope };
         let output_legacy_scope = self.build_reduced_graph(fragment, parent_scope);
         self.output_legacy_scopes.insert(expansion, output_legacy_scope);
     }
@@ -186,7 +185,9 @@ impl<'a> base::Resolver for Resolver<'a> {
         let (ext, res) = self.smart_resolve_macro_path(path, kind, parent_scope, force)?;
 
         let span = invoc.span();
-        invoc.expansion_data.id.set_expn_info(ext.expn_info(span, fast_print_path(path)));
+        invoc.expansion_data.id.set_expn_info(
+            ext.expn_info(parent_scope.expansion, span, fast_print_path(path))
+        );
 
         if let Res::Def(_, def_id) = res {
             if after_derive {
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 8eacb96e3ff96..734b566b3ad1d 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -640,10 +640,11 @@ impl SyntaxExtension {
         SyntaxExtension::default(SyntaxExtensionKind::NonMacroAttr { mark_used }, edition)
     }
 
-    pub fn expn_info(&self, call_site: Span, descr: Symbol) -> ExpnInfo {
+    pub fn expn_info(&self, parent: ExpnId, call_site: Span, descr: Symbol) -> ExpnInfo {
         ExpnInfo {
-            call_site,
             kind: ExpnKind::Macro(self.macro_kind(), descr),
+            parent,
+            call_site,
             def_site: self.span,
             default_transparency: self.default_transparency,
             allow_internal_unstable: self.allow_internal_unstable.clone(),
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 6f3e8f14b0b22..4233d5c0a222e 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -353,7 +353,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                 derives.reserve(traits.len());
                 invocations.reserve(traits.len());
                 for path in traits {
-                    let expn_id = ExpnId::fresh(self.cx.current_expansion.id, None);
+                    let expn_id = ExpnId::fresh(None);
                     derives.push(expn_id);
                     invocations.push(Invocation {
                         kind: InvocationKind::Derive { path, item: item.clone() },
@@ -800,13 +800,16 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
         // with exception of the derive container case which is not resolved and can get
         // its expansion info immediately.
         let expn_info = match &kind {
-            InvocationKind::DeriveContainer { item, .. } => Some(ExpnInfo::default(
-                ExpnKind::Macro(MacroKind::Attr, sym::derive),
-                item.span(), self.cx.parse_sess.edition,
-            )),
+            InvocationKind::DeriveContainer { item, .. } => Some(ExpnInfo {
+                parent: self.cx.current_expansion.id,
+                ..ExpnInfo::default(
+                    ExpnKind::Macro(MacroKind::Attr, sym::derive),
+                    item.span(), self.cx.parse_sess.edition,
+                )
+            }),
             _ => None,
         };
-        let expn_id = ExpnId::fresh(self.cx.current_expansion.id, expn_info);
+        let expn_id = ExpnId::fresh(expn_info);
         self.invocations.push(Invocation {
             kind,
             fragment_kind,
diff --git a/src/libsyntax_ext/deriving/clone.rs b/src/libsyntax_ext/deriving/clone.rs
index 5a02ae0afb969..73df625d5ee60 100644
--- a/src/libsyntax_ext/deriving/clone.rs
+++ b/src/libsyntax_ext/deriving/clone.rs
@@ -35,7 +35,7 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt<'_>,
             match annitem.node {
                 ItemKind::Struct(_, Generics { ref params, .. }) |
                 ItemKind::Enum(_, Generics { ref params, .. }) => {
-                    let container_id = cx.current_expansion.id.parent();
+                    let container_id = cx.current_expansion.id.expn_info().parent;
                     if cx.resolver.has_derives(container_id, SpecialDerives::COPY) &&
                         !params.iter().any(|param| match param.kind {
                             ast::GenericParamKind::Type { .. } => true,
diff --git a/src/libsyntax_ext/deriving/cmp/eq.rs b/src/libsyntax_ext/deriving/cmp/eq.rs
index 5d7c4a84389c6..1ef34a6800414 100644
--- a/src/libsyntax_ext/deriving/cmp/eq.rs
+++ b/src/libsyntax_ext/deriving/cmp/eq.rs
@@ -13,7 +13,7 @@ pub fn expand_deriving_eq(cx: &mut ExtCtxt<'_>,
                           mitem: &MetaItem,
                           item: &Annotatable,
                           push: &mut dyn FnMut(Annotatable)) {
-    cx.resolver.add_derives(cx.current_expansion.id.parent(), SpecialDerives::EQ);
+    cx.resolver.add_derives(cx.current_expansion.id.expn_info().parent, SpecialDerives::EQ);
 
     let inline = cx.meta_word(span, sym::inline);
     let hidden = cx.meta_list_item_word(span, sym::hidden);
diff --git a/src/libsyntax_ext/deriving/cmp/partial_eq.rs b/src/libsyntax_ext/deriving/cmp/partial_eq.rs
index 7d7c4ae22a8a6..76befc98591ef 100644
--- a/src/libsyntax_ext/deriving/cmp/partial_eq.rs
+++ b/src/libsyntax_ext/deriving/cmp/partial_eq.rs
@@ -13,7 +13,7 @@ pub fn expand_deriving_partial_eq(cx: &mut ExtCtxt<'_>,
                                   mitem: &MetaItem,
                                   item: &Annotatable,
                                   push: &mut dyn FnMut(Annotatable)) {
-    cx.resolver.add_derives(cx.current_expansion.id.parent(), SpecialDerives::PARTIAL_EQ);
+    cx.resolver.add_derives(cx.current_expansion.id.expn_info().parent, SpecialDerives::PARTIAL_EQ);
 
     // structures are equal if all fields are equal, and non equal, if
     // any fields are not equal or if the enum variants are different
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index 4bf004a71e4da..6b739e27eee89 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -425,7 +425,7 @@ impl<'a> TraitDef<'a> {
                         return;
                     }
                 };
-                let container_id = cx.current_expansion.id.parent();
+                let container_id = cx.current_expansion.id.expn_info().parent;
                 let is_always_copy =
                     cx.resolver.has_derives(container_id, SpecialDerives::COPY) &&
                     has_no_type_params;
diff --git a/src/libsyntax_ext/plugin_macro_defs.rs b/src/libsyntax_ext/plugin_macro_defs.rs
index 15737314b2239..b34a250881a31 100644
--- a/src/libsyntax_ext/plugin_macro_defs.rs
+++ b/src/libsyntax_ext/plugin_macro_defs.rs
@@ -11,7 +11,7 @@ use syntax::source_map::respan;
 use syntax::symbol::sym;
 use syntax::tokenstream::*;
 use syntax_pos::{Span, DUMMY_SP};
-use syntax_pos::hygiene::{ExpnId, ExpnInfo, ExpnKind, MacroKind};
+use syntax_pos::hygiene::{ExpnInfo, ExpnKind, MacroKind};
 
 use std::mem;
 
@@ -43,7 +43,7 @@ pub fn inject(
 ) {
     if !named_exts.is_empty() {
         let mut extra_items = Vec::new();
-        let span = DUMMY_SP.fresh_expansion(ExpnId::root(), ExpnInfo::allow_unstable(
+        let span = DUMMY_SP.fresh_expansion(ExpnInfo::allow_unstable(
             ExpnKind::Macro(MacroKind::Attr, sym::plugin), DUMMY_SP, edition,
             [sym::rustc_attrs][..].into(),
         ));
diff --git a/src/libsyntax_ext/proc_macro_harness.rs b/src/libsyntax_ext/proc_macro_harness.rs
index 62c74b2b9c6b4..9d8a8c17ba2d8 100644
--- a/src/libsyntax_ext/proc_macro_harness.rs
+++ b/src/libsyntax_ext/proc_macro_harness.rs
@@ -6,7 +6,6 @@ use syntax::attr;
 use syntax::source_map::{ExpnInfo, ExpnKind, respan};
 use syntax::ext::base::{ExtCtxt, MacroKind};
 use syntax::ext::expand::{AstFragment, ExpansionConfig};
-use syntax::ext::hygiene::ExpnId;
 use syntax::ext::proc_macro::is_proc_macro_attr;
 use syntax::parse::ParseSess;
 use syntax::ptr::P;
@@ -328,7 +327,7 @@ fn mk_decls(
     custom_attrs: &[ProcMacroDef],
     custom_macros: &[ProcMacroDef],
 ) -> P<ast::Item> {
-    let span = DUMMY_SP.fresh_expansion(ExpnId::root(), ExpnInfo::allow_unstable(
+    let span = DUMMY_SP.fresh_expansion(ExpnInfo::allow_unstable(
         ExpnKind::Macro(MacroKind::Attr, sym::proc_macro), DUMMY_SP, cx.parse_sess.edition,
         [sym::rustc_attrs, sym::proc_macro_internals][..].into(),
     ));
diff --git a/src/libsyntax_ext/standard_library_imports.rs b/src/libsyntax_ext/standard_library_imports.rs
index 4382fb8af8585..c004124865223 100644
--- a/src/libsyntax_ext/standard_library_imports.rs
+++ b/src/libsyntax_ext/standard_library_imports.rs
@@ -1,6 +1,6 @@
 use syntax::{ast, attr};
 use syntax::edition::Edition;
-use syntax::ext::hygiene::{ExpnId, MacroKind};
+use syntax::ext::hygiene::MacroKind;
 use syntax::ptr::P;
 use syntax::source_map::{ExpnInfo, ExpnKind, dummy_spanned, respan};
 use syntax::symbol::{Ident, Symbol, kw, sym};
@@ -55,7 +55,7 @@ pub fn inject(
     // the prelude.
     let name = names[0];
 
-    let span = DUMMY_SP.fresh_expansion(ExpnId::root(), ExpnInfo::allow_unstable(
+    let span = DUMMY_SP.fresh_expansion(ExpnInfo::allow_unstable(
         ExpnKind::Macro(MacroKind::Attr, sym::std_inject), DUMMY_SP, edition,
         [sym::prelude_import][..].into(),
     ));
diff --git a/src/libsyntax_ext/test_harness.rs b/src/libsyntax_ext/test_harness.rs
index ab108290a938d..3fb1c1bd02240 100644
--- a/src/libsyntax_ext/test_harness.rs
+++ b/src/libsyntax_ext/test_harness.rs
@@ -5,9 +5,8 @@ use smallvec::{smallvec, SmallVec};
 use syntax::ast::{self, Ident};
 use syntax::attr;
 use syntax::entry::{self, EntryPointType};
-use syntax::ext::base::{ExtCtxt, Resolver};
+use syntax::ext::base::{ExtCtxt, MacroKind, Resolver};
 use syntax::ext::expand::{AstFragment, ExpansionConfig};
-use syntax::ext::hygiene::{ExpnId, MacroKind};
 use syntax::feature_gate::Features;
 use syntax::mut_visit::{*, ExpectOne};
 use syntax::parse::ParseSess;
@@ -269,7 +268,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
     //            #![main]
     //            test::test_main_static(&[..tests]);
     //        }
-    let sp = DUMMY_SP.fresh_expansion(ExpnId::root(), ExpnInfo::allow_unstable(
+    let sp = DUMMY_SP.fresh_expansion(ExpnInfo::allow_unstable(
         ExpnKind::Macro(MacroKind::Attr, sym::test_case), DUMMY_SP, cx.ext_cx.parse_sess.edition,
         [sym::main, sym::test, sym::rustc_attrs][..].into(),
     ));
diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs
index 743bd437ee5b6..1dba466625ae8 100644
--- a/src/libsyntax_pos/hygiene.rs
+++ b/src/libsyntax_pos/hygiene.rs
@@ -56,16 +56,6 @@ struct SyntaxContextData {
 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
 pub struct ExpnId(u32);
 
-// FIXME: Find a way to merge this with `ExpnInfo`.
-#[derive(Debug)]
-struct InternalExpnData {
-    parent: ExpnId,
-    /// Each expansion should have an associated expansion info, but sometimes there's a delay
-    /// between creation of an expansion ID and obtaining its info (e.g. macros are collected
-    /// first and then resolved later), so we use an `Option` here.
-    expn_info: Option<ExpnInfo>,
-}
-
 /// A property of a macro expansion that determines how identifiers
 /// produced by that expansion are resolved.
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Hash, Debug, RustcEncodable, RustcDecodable)]
@@ -86,8 +76,8 @@ pub enum Transparency {
 }
 
 impl ExpnId {
-    pub fn fresh(parent: ExpnId, expn_info: Option<ExpnInfo>) -> Self {
-        HygieneData::with(|data| data.fresh_expn(parent, expn_info))
+    pub fn fresh(expn_info: Option<ExpnInfo>) -> Self {
+        HygieneData::with(|data| data.fresh_expn(expn_info))
     }
 
     /// The ID of the theoretical expansion that generates freshly parsed, unexpanded AST.
@@ -106,11 +96,6 @@ impl ExpnId {
         ExpnId(raw)
     }
 
-    #[inline]
-    pub fn parent(self) -> ExpnId {
-        HygieneData::with(|data| data.parent_expn(self))
-    }
-
     #[inline]
     pub fn expn_info(self) -> ExpnInfo {
         HygieneData::with(|data| data.expn_info(self).clone())
@@ -119,7 +104,7 @@ impl ExpnId {
     #[inline]
     pub fn set_expn_info(self, info: ExpnInfo) {
         HygieneData::with(|data| {
-            let old_info = &mut data.expn_data[self.0 as usize].expn_info;
+            let old_info = &mut data.expn_data[self.0 as usize];
             assert!(old_info.is_none(), "expansion info is reset for an expansion ID");
             *old_info = Some(info);
         })
@@ -150,7 +135,10 @@ impl ExpnId {
 
 #[derive(Debug)]
 crate struct HygieneData {
-    expn_data: Vec<InternalExpnData>,
+    /// Each expansion should have an associated expansion info, but sometimes there's a delay
+    /// between creation of an expansion ID and obtaining its info (e.g. macros are collected
+    /// first and then resolved later), so we use an `Option` here.
+    expn_data: Vec<Option<ExpnInfo>>,
     syntax_context_data: Vec<SyntaxContextData>,
     syntax_context_map: FxHashMap<(SyntaxContext, ExpnId, Transparency), SyntaxContext>,
 }
@@ -158,10 +146,7 @@ crate struct HygieneData {
 impl HygieneData {
     crate fn new(edition: Edition) -> Self {
         HygieneData {
-            expn_data: vec![InternalExpnData {
-                parent: ExpnId::root(),
-                expn_info: Some(ExpnInfo::default(ExpnKind::Root, DUMMY_SP, edition)),
-            }],
+            expn_data: vec![Some(ExpnInfo::default(ExpnKind::Root, DUMMY_SP, edition))],
             syntax_context_data: vec![SyntaxContextData {
                 outer_expn: ExpnId::root(),
                 outer_transparency: Transparency::Opaque,
@@ -178,17 +163,13 @@ impl HygieneData {
         GLOBALS.with(|globals| f(&mut *globals.hygiene_data.borrow_mut()))
     }
 
-    fn fresh_expn(&mut self, parent: ExpnId, expn_info: Option<ExpnInfo>) -> ExpnId {
-        self.expn_data.push(InternalExpnData { parent, expn_info });
+    fn fresh_expn(&mut self, expn_info: Option<ExpnInfo>) -> ExpnId {
+        self.expn_data.push(expn_info);
         ExpnId(self.expn_data.len() as u32 - 1)
     }
 
-    fn parent_expn(&self, expn_id: ExpnId) -> ExpnId {
-        self.expn_data[expn_id.0 as usize].parent
-    }
-
     fn expn_info(&self, expn_id: ExpnId) -> &ExpnInfo {
-        self.expn_data[expn_id.0 as usize].expn_info.as_ref()
+        self.expn_data[expn_id.0 as usize].as_ref()
             .expect("no expansion info for an expansion ID")
     }
 
@@ -197,7 +178,7 @@ impl HygieneData {
             if expn_id == ExpnId::root() {
                 return false;
             }
-            expn_id = self.parent_expn(expn_id);
+            expn_id = self.expn_info(expn_id).parent;
         }
         true
     }
@@ -593,9 +574,9 @@ impl Span {
     /// other compiler-generated code to set per-span properties like allowed unstable features.
     /// The returned span belongs to the created expansion and has the new properties,
     /// but its location is inherited from the current span.
-    pub fn fresh_expansion(self, parent: ExpnId, expn_info: ExpnInfo) -> Span {
+    pub fn fresh_expansion(self, expn_info: ExpnInfo) -> Span {
         HygieneData::with(|data| {
-            let expn_id = data.fresh_expn(parent, Some(expn_info));
+            let expn_id = data.fresh_expn(Some(expn_info));
             self.with_ctxt(data.apply_mark(SyntaxContext::root(), expn_id))
         })
     }
@@ -606,6 +587,10 @@ impl Span {
 #[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
 pub struct ExpnInfo {
     // --- The part unique to each expansion.
+    /// The kind of this expansion - macro or compiler desugaring.
+    pub kind: ExpnKind,
+    /// The expansion that produced this expansion.
+    pub parent: ExpnId,
     /// The location of the actual macro invocation or syntax sugar , e.g.
     /// `let x = foo!();` or `if let Some(y) = x {}`
     ///
@@ -616,8 +601,6 @@ pub struct ExpnInfo {
     /// call_site span would have its own ExpnInfo, with the call_site
     /// pointing to the `foo!` invocation.
     pub call_site: Span,
-    /// The kind of this expansion - macro or compiler desugaring.
-    pub kind: ExpnKind,
 
     // --- The part specific to the macro/desugaring definition.
     // --- FIXME: Share it between expansions with the same definition.
@@ -644,8 +627,9 @@ impl ExpnInfo {
     /// Constructs an expansion info with default properties.
     pub fn default(kind: ExpnKind, call_site: Span, edition: Edition) -> ExpnInfo {
         ExpnInfo {
-            call_site,
             kind,
+            parent: ExpnId::root(),
+            call_site,
             def_site: DUMMY_SP,
             default_transparency: Transparency::SemiTransparent,
             allow_internal_unstable: None,
@@ -753,6 +737,18 @@ impl DesugaringKind {
     }
 }
 
+impl Encodable for ExpnId {
+    fn encode<E: Encoder>(&self, _: &mut E) -> Result<(), E::Error> {
+        Ok(()) // FIXME(jseyfried) intercrate hygiene
+    }
+}
+
+impl Decodable for ExpnId {
+    fn decode<D: Decoder>(_: &mut D) -> Result<Self, D::Error> {
+        Ok(ExpnId::root()) // FIXME(jseyfried) intercrate hygiene
+    }
+}
+
 impl Encodable for SyntaxContext {
     fn encode<E: Encoder>(&self, _: &mut E) -> Result<(), E::Error> {
         Ok(()) // FIXME(jseyfried) intercrate hygiene
@@ -760,7 +756,7 @@ impl Encodable for SyntaxContext {
 }
 
 impl Decodable for SyntaxContext {
-    fn decode<D: Decoder>(_: &mut D) -> Result<SyntaxContext, D::Error> {
+    fn decode<D: Decoder>(_: &mut D) -> Result<Self, D::Error> {
         Ok(SyntaxContext::root()) // FIXME(jseyfried) intercrate hygiene
     }
 }

From 74190a5e1c7439b001296fbc41da67682fd1d9bf Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Tue, 13 Aug 2019 22:48:27 +0300
Subject: [PATCH 30/35] syntax_pos: Remove the duplicate global edition

It was introduced to avoid going through `hygiene_data`, but now it's read only once, when `ParseSess` is created, so going through a lock is ok.
---
 src/libsyntax/parse/lexer/tests.rs | 32 ++++--------------------------
 src/libsyntax/parse/mod.rs         |  3 ++-
 src/libsyntax_pos/edition.rs       |  5 -----
 src/libsyntax_pos/lib.rs           |  2 --
 4 files changed, 6 insertions(+), 36 deletions(-)

diff --git a/src/libsyntax/parse/lexer/tests.rs b/src/libsyntax/parse/lexer/tests.rs
index 1e4d9048b41b8..94570140996f1 100644
--- a/src/libsyntax/parse/lexer/tests.rs
+++ b/src/libsyntax/parse/lexer/tests.rs
@@ -1,41 +1,17 @@
 use super::*;
 
-use crate::ast::CrateConfig;
 use crate::symbol::Symbol;
 use crate::source_map::{SourceMap, FilePathMapping};
-use crate::feature_gate::UnstableFeatures;
 use crate::parse::token;
-use crate::diagnostics::plugin::ErrorMap;
 use crate::with_default_globals;
 use std::io;
 use std::path::PathBuf;
-use syntax_pos::{BytePos, Span, edition::Edition};
-use rustc_data_structures::fx::{FxHashSet, FxHashMap};
-use rustc_data_structures::sync::{Lock, Once};
+use errors::{Handler, emitter::EmitterWriter};
+use syntax_pos::{BytePos, Span};
 
 fn mk_sess(sm: Lrc<SourceMap>) -> ParseSess {
-    let emitter = errors::emitter::EmitterWriter::new(Box::new(io::sink()),
-                                                        Some(sm.clone()),
-                                                        false,
-                                                        false,
-                                                        false);
-    ParseSess {
-        span_diagnostic: errors::Handler::with_emitter(true, None, Box::new(emitter)),
-        unstable_features: UnstableFeatures::from_environment(),
-        config: CrateConfig::default(),
-        included_mod_stack: Lock::new(Vec::new()),
-        source_map: sm,
-        missing_fragment_specifiers: Lock::new(FxHashSet::default()),
-        raw_identifier_spans: Lock::new(Vec::new()),
-        registered_diagnostics: Lock::new(ErrorMap::new()),
-        buffered_lints: Lock::new(vec![]),
-        edition: Edition::from_session(),
-        ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
-        param_attr_spans: Lock::new(Vec::new()),
-        let_chains_spans: Lock::new(Vec::new()),
-        async_closure_spans: Lock::new(Vec::new()),
-        injected_crate_name: Once::new(),
-    }
+    let emitter = EmitterWriter::new(Box::new(io::sink()), Some(sm.clone()), false, false, false);
+    ParseSess::with_span_handler(Handler::with_emitter(true, None, Box::new(emitter)), sm)
 }
 
 // open a string reader for the given string
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 80aa7a35266eb..a1bcc455eb4cf 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -16,6 +16,7 @@ use errors::{Applicability, FatalError, Level, Handler, ColorConfig, Diagnostic,
 use rustc_data_structures::sync::{Lrc, Lock, Once};
 use syntax_pos::{Span, SourceFile, FileName, MultiSpan};
 use syntax_pos::edition::Edition;
+use syntax_pos::hygiene::ExpnId;
 
 use rustc_data_structures::fx::{FxHashSet, FxHashMap};
 use std::borrow::Cow;
@@ -86,7 +87,7 @@ impl ParseSess {
             included_mod_stack: Lock::new(vec![]),
             source_map,
             buffered_lints: Lock::new(vec![]),
-            edition: Edition::from_session(),
+            edition: ExpnId::root().expn_info().edition,
             ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
             param_attr_spans: Lock::new(Vec::new()),
             let_chains_spans: Lock::new(Vec::new()),
diff --git a/src/libsyntax_pos/edition.rs b/src/libsyntax_pos/edition.rs
index 20216568426fe..00cd00f283784 100644
--- a/src/libsyntax_pos/edition.rs
+++ b/src/libsyntax_pos/edition.rs
@@ -1,7 +1,6 @@
 use crate::symbol::{Symbol, sym};
 use std::fmt;
 use std::str::FromStr;
-use crate::GLOBALS;
 
 /// The edition of the compiler (RFC 2052)
 #[derive(Clone, Copy, Hash, PartialEq, PartialOrd, Debug, RustcEncodable, RustcDecodable, Eq)]
@@ -39,10 +38,6 @@ impl fmt::Display for Edition {
 }
 
 impl Edition {
-    pub fn from_session() -> Edition {
-        GLOBALS.with(|globals| globals.edition)
-    }
-
     pub fn lint_name(&self) -> &'static str {
         match *self {
             Edition::Edition2015 => "rust_2015_compatibility",
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index 7af426eaa13f7..ae538677a3aac 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -49,7 +49,6 @@ pub struct Globals {
     symbol_interner: Lock<symbol::Interner>,
     span_interner: Lock<span_encoding::SpanInterner>,
     hygiene_data: Lock<hygiene::HygieneData>,
-    edition: Edition,
 }
 
 impl Globals {
@@ -58,7 +57,6 @@ impl Globals {
             symbol_interner: Lock::new(symbol::Interner::fresh()),
             span_interner: Lock::new(span_encoding::SpanInterner::default()),
             hygiene_data: Lock::new(hygiene::HygieneData::new(edition)),
-            edition,
         }
     }
 }

From 650f19aeae94eff687382859603929cd2dd463bc Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Tue, 13 Aug 2019 23:39:48 +0300
Subject: [PATCH 31/35] hygiene: Merge a tiny bit of the "share expansion
 definition data" PR

---
 src/librustc/hir/lowering.rs | 1 -
 src/libsyntax_pos/hygiene.rs | 4 +++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 0b7dacf8383e8..8c1ce5983b8c5 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -705,7 +705,6 @@ impl<'a> LoweringContext<'a> {
         allow_internal_unstable: Option<Lrc<[Symbol]>>,
     ) -> Span {
         span.fresh_expansion(ExpnInfo {
-            def_site: span,
             allow_internal_unstable,
             ..ExpnInfo::default(ExpnKind::Desugaring(reason), span, self.sess.edition())
         })
diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs
index 1dba466625ae8..4d9496f94fbde 100644
--- a/src/libsyntax_pos/hygiene.rs
+++ b/src/libsyntax_pos/hygiene.rs
@@ -603,7 +603,9 @@ pub struct ExpnInfo {
     pub call_site: Span,
 
     // --- The part specific to the macro/desugaring definition.
-    // --- FIXME: Share it between expansions with the same definition.
+    // --- It may be reasonable to share this part between expansions with the same definition,
+    // --- but such sharing is known to bring some minor inconveniences without also bringing
+    // --- noticeable perf improvements (PR #62898).
     /// The span of the macro definition (possibly dummy).
     /// This span serves only informational purpose and is not used for resolution.
     pub def_site: Span,

From 136db2235a754f91f8a0a6bf6d985d77fe97f8db Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Tue, 13 Aug 2019 23:56:42 +0300
Subject: [PATCH 32/35] hygiene: `ExpnInfo` -> `ExpnData`

For naming consistency with everything else in this area
---
 src/librustc/hir/lowering.rs                  |  6 +-
 src/librustc/ich/hcx.rs                       |  2 +-
 src/librustc/ich/impls_syntax.rs              |  2 +-
 src/librustc/lint/internal.rs                 |  8 +-
 src/librustc/lint/mod.rs                      | 10 +--
 src/librustc/traits/error_reporting.rs        |  6 +-
 src/librustc/ty/query/on_disk_cache.rs        | 68 +++++++-------
 src/librustc_codegen_ssa/back/write.rs        |  2 +-
 src/librustc_lint/unused.rs                   |  2 +-
 src/librustc_resolve/macros.rs                | 10 +--
 src/libsyntax/ext/base.rs                     | 18 ++--
 src/libsyntax/ext/expand.rs                   | 20 ++---
 src/libsyntax/ext/proc_macro_server.rs        |  2 +-
 src/libsyntax/parse/mod.rs                    |  2 +-
 src/libsyntax/source_map.rs                   | 14 +--
 src/libsyntax_ext/deriving/clone.rs           |  2 +-
 src/libsyntax_ext/deriving/cmp/eq.rs          |  2 +-
 src/libsyntax_ext/deriving/cmp/partial_eq.rs  |  2 +-
 src/libsyntax_ext/deriving/generic/mod.rs     |  2 +-
 src/libsyntax_ext/plugin_macro_defs.rs        |  4 +-
 src/libsyntax_ext/proc_macro_harness.rs       |  4 +-
 src/libsyntax_ext/standard_library_imports.rs |  4 +-
 src/libsyntax_ext/test_harness.rs             |  4 +-
 src/libsyntax_pos/hygiene.rs                  | 90 +++++++++----------
 src/libsyntax_pos/lib.rs                      | 50 +++++------
 25 files changed, 168 insertions(+), 168 deletions(-)

diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 8c1ce5983b8c5..0f6e834ca26df 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -67,7 +67,7 @@ use syntax::errors;
 use syntax::ext::base::SpecialDerives;
 use syntax::ext::hygiene::ExpnId;
 use syntax::print::pprust;
-use syntax::source_map::{respan, ExpnInfo, ExpnKind, DesugaringKind, Spanned};
+use syntax::source_map::{respan, ExpnData, ExpnKind, DesugaringKind, Spanned};
 use syntax::symbol::{kw, sym, Symbol};
 use syntax::tokenstream::{TokenStream, TokenTree};
 use syntax::parse::token::{self, Token};
@@ -704,9 +704,9 @@ impl<'a> LoweringContext<'a> {
         span: Span,
         allow_internal_unstable: Option<Lrc<[Symbol]>>,
     ) -> Span {
-        span.fresh_expansion(ExpnInfo {
+        span.fresh_expansion(ExpnData {
             allow_internal_unstable,
-            ..ExpnInfo::default(ExpnKind::Desugaring(reason), span, self.sess.edition())
+            ..ExpnData::default(ExpnKind::Desugaring(reason), span, self.sess.edition())
         })
     }
 
diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs
index 39f6b0d434440..e77faea1e4c58 100644
--- a/src/librustc/ich/hcx.rs
+++ b/src/librustc/ich/hcx.rs
@@ -370,7 +370,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for Span {
                 }
 
                 let mut hasher = StableHasher::new();
-                expn_id.expn_info().hash_stable(hcx, &mut hasher);
+                expn_id.expn_data().hash_stable(hcx, &mut hasher);
                 let sub_hash: Fingerprint = hasher.finish();
                 let sub_hash = sub_hash.to_smaller_hash();
                 cache.borrow_mut().insert(expn_id, sub_hash);
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
index 22e2cff359520..7003f71c8baa0 100644
--- a/src/librustc/ich/impls_syntax.rs
+++ b/src/librustc/ich/impls_syntax.rs
@@ -397,7 +397,7 @@ impl_stable_hash_for!(enum ::syntax_pos::hygiene::Transparency {
     Opaque,
 });
 
-impl_stable_hash_for!(struct ::syntax_pos::hygiene::ExpnInfo {
+impl_stable_hash_for!(struct ::syntax_pos::hygiene::ExpnData {
     kind,
     parent -> _,
     call_site,
diff --git a/src/librustc/lint/internal.rs b/src/librustc/lint/internal.rs
index 29106fe000bb6..be73b305e2c50 100644
--- a/src/librustc/lint/internal.rs
+++ b/src/librustc/lint/internal.rs
@@ -227,10 +227,10 @@ impl EarlyLintPass for LintPassImpl {
         if let ItemKind::Impl(_, _, _, _, Some(lint_pass), _, _) = &item.node {
             if let Some(last) = lint_pass.path.segments.last() {
                 if last.ident.name == sym::LintPass {
-                    let expn_info = lint_pass.path.span.ctxt().outer_expn_info();
-                    let call_site = expn_info.call_site;
-                    if expn_info.kind.descr() != sym::impl_lint_pass &&
-                       call_site.ctxt().outer_expn_info().kind.descr() != sym::declare_lint_pass {
+                    let expn_data = lint_pass.path.span.ctxt().outer_expn_data();
+                    let call_site = expn_data.call_site;
+                    if expn_data.kind.descr() != sym::impl_lint_pass &&
+                       call_site.ctxt().outer_expn_data().kind.descr() != sym::declare_lint_pass {
                         cx.struct_span_lint(
                             LINT_PASS_IMPL_WITHOUT_MACRO,
                             lint_pass.path.span,
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 3729ee81f5c65..2b58627cdea56 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -885,16 +885,16 @@ pub fn provide(providers: &mut Providers<'_>) {
 /// This is used to test whether a lint should not even begin to figure out whether it should
 /// be reported on the current node.
 pub fn in_external_macro(sess: &Session, span: Span) -> bool {
-    let expn_info = span.ctxt().outer_expn_info();
-    match expn_info.kind {
+    let expn_data = span.ctxt().outer_expn_data();
+    match expn_data.kind {
         ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop) => false,
         ExpnKind::Desugaring(_) => true, // well, it's "external"
         ExpnKind::Macro(MacroKind::Bang, _) => {
-            if expn_info.def_site.is_dummy() {
+            if expn_data.def_site.is_dummy() {
                 // dummy span for the def_site means it's an external macro
                 return true;
             }
-            match sess.source_map().span_to_snippet(expn_info.def_site) {
+            match sess.source_map().span_to_snippet(expn_data.def_site) {
                 Ok(code) => !code.starts_with("macro_rules"),
                 // no snippet = external macro or compiler-builtin expansion
                 Err(_) => true,
@@ -906,7 +906,7 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool {
 
 /// Returns whether `span` originates in a derive macro's expansion
 pub fn in_derive_expansion(span: Span) -> bool {
-    if let ExpnKind::Macro(MacroKind::Derive, _) = span.ctxt().outer_expn_info().kind {
+    if let ExpnKind::Macro(MacroKind::Derive, _) = span.ctxt().outer_expn_data().kind {
         return true;
     }
     false
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 20568d4709b64..ba92e851141a6 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -61,9 +61,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             // We want to ignore desugarings here: spans are equivalent even
             // if one is the result of a desugaring and the other is not.
             let mut span = error.obligation.cause.span;
-            let expn_info = span.ctxt().outer_expn_info();
-            if let ExpnKind::Desugaring(_) = expn_info.kind {
-                span = expn_info.call_site;
+            let expn_data = span.ctxt().outer_expn_data();
+            if let ExpnKind::Desugaring(_) = expn_data.kind {
+                span = expn_data.call_site;
             }
 
             error_map.entry(span).or_default().push(
diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs
index 351b9988bb25c..8bf01970eb592 100644
--- a/src/librustc/ty/query/on_disk_cache.rs
+++ b/src/librustc/ty/query/on_disk_cache.rs
@@ -23,16 +23,16 @@ use std::mem;
 use syntax::ast::NodeId;
 use syntax::source_map::{SourceMap, StableSourceFileId};
 use syntax_pos::{BytePos, Span, DUMMY_SP, SourceFile};
-use syntax_pos::hygiene::{ExpnId, SyntaxContext, ExpnInfo};
+use syntax_pos::hygiene::{ExpnId, SyntaxContext, ExpnData};
 
 const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE;
 
 const TAG_CLEAR_CROSS_CRATE_CLEAR: u8 = 0;
 const TAG_CLEAR_CROSS_CRATE_SET: u8 = 1;
 
-const TAG_NO_EXPANSION_INFO: u8 = 0;
-const TAG_EXPANSION_INFO_SHORTHAND: u8 = 1;
-const TAG_EXPANSION_INFO_INLINE: u8 = 2;
+const TAG_NO_EXPN_DATA: u8 = 0;
+const TAG_EXPN_DATA_SHORTHAND: u8 = 1;
+const TAG_EXPN_DATA_INLINE: u8 = 2;
 
 const TAG_VALID_SPAN: u8 = 0;
 const TAG_INVALID_SPAN: u8 = 1;
@@ -58,7 +58,7 @@ pub struct OnDiskCache<'sess> {
 
     // These two fields caches that are populated lazily during decoding.
     file_index_to_file: Lock<FxHashMap<SourceFileIndex, Lrc<SourceFile>>>,
-    synthetic_expansion_infos: Lock<FxHashMap<AbsoluteBytePos, SyntaxContext>>,
+    synthetic_syntax_contexts: Lock<FxHashMap<AbsoluteBytePos, SyntaxContext>>,
 
     // A map from dep-node to the position of the cached query result in
     // `serialized_data`.
@@ -135,7 +135,7 @@ impl<'sess> OnDiskCache<'sess> {
             current_diagnostics: Default::default(),
             query_result_index: footer.query_result_index.into_iter().collect(),
             prev_diagnostics_index: footer.diagnostics_index.into_iter().collect(),
-            synthetic_expansion_infos: Default::default(),
+            synthetic_syntax_contexts: Default::default(),
             alloc_decoding_state: AllocDecodingState::new(footer.interpret_alloc_index),
         }
     }
@@ -151,7 +151,7 @@ impl<'sess> OnDiskCache<'sess> {
             current_diagnostics: Default::default(),
             query_result_index: Default::default(),
             prev_diagnostics_index: Default::default(),
-            synthetic_expansion_infos: Default::default(),
+            synthetic_syntax_contexts: Default::default(),
             alloc_decoding_state: AllocDecodingState::new(Vec::new()),
         }
     }
@@ -185,7 +185,7 @@ impl<'sess> OnDiskCache<'sess> {
                 encoder,
                 type_shorthands: Default::default(),
                 predicate_shorthands: Default::default(),
-                expn_info_shorthands: Default::default(),
+                expn_data_shorthands: Default::default(),
                 interpret_allocs: Default::default(),
                 interpret_allocs_inverse: Vec::new(),
                 source_map: CachingSourceMapView::new(tcx.sess.source_map()),
@@ -383,7 +383,7 @@ impl<'sess> OnDiskCache<'sess> {
             cnum_map: self.cnum_map.get(),
             file_index_to_file: &self.file_index_to_file,
             file_index_to_stable_id: &self.file_index_to_stable_id,
-            synthetic_expansion_infos: &self.synthetic_expansion_infos,
+            synthetic_syntax_contexts: &self.synthetic_syntax_contexts,
             alloc_decoding_session: self.alloc_decoding_state.new_decoding_session(),
         };
 
@@ -440,7 +440,7 @@ struct CacheDecoder<'a, 'tcx> {
     opaque: opaque::Decoder<'a>,
     source_map: &'a SourceMap,
     cnum_map: &'a IndexVec<CrateNum, Option<CrateNum>>,
-    synthetic_expansion_infos: &'a Lock<FxHashMap<AbsoluteBytePos, SyntaxContext>>,
+    synthetic_syntax_contexts: &'a Lock<FxHashMap<AbsoluteBytePos, SyntaxContext>>,
     file_index_to_file: &'a Lock<FxHashMap<SourceFileIndex, Lrc<SourceFile>>>,
     file_index_to_stable_id: &'a FxHashMap<SourceFileIndex, StableSourceFileId>,
     alloc_decoding_session: AllocDecodingSession<'a>,
@@ -586,37 +586,37 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx> {
         let lo = file_lo.lines[line_lo - 1] + col_lo;
         let hi = lo + len;
 
-        let expn_info_tag = u8::decode(self)?;
+        let expn_data_tag = u8::decode(self)?;
 
-        // FIXME(mw): This method does not restore `ExpnInfo::parent` or
+        // FIXME(mw): This method does not restore `ExpnData::parent` or
         // `SyntaxContextData::prev_ctxt` or `SyntaxContextData::opaque`. These things
         // don't seem to be used after HIR lowering, so everything should be fine
         // as long as incremental compilation does not kick in before that.
         let location = || Span::with_root_ctxt(lo, hi);
-        let recover_from_expn_info = |this: &Self, expn_info, pos| {
-            let span = location().fresh_expansion(expn_info);
-            this.synthetic_expansion_infos.borrow_mut().insert(pos, span.ctxt());
+        let recover_from_expn_data = |this: &Self, expn_data, pos| {
+            let span = location().fresh_expansion(expn_data);
+            this.synthetic_syntax_contexts.borrow_mut().insert(pos, span.ctxt());
             span
         };
-        Ok(match expn_info_tag {
-            TAG_NO_EXPANSION_INFO => {
+        Ok(match expn_data_tag {
+            TAG_NO_EXPN_DATA => {
                 location()
             }
-            TAG_EXPANSION_INFO_INLINE => {
-                let expn_info = Decodable::decode(self)?;
-                recover_from_expn_info(
-                    self, expn_info, AbsoluteBytePos::new(self.opaque.position())
+            TAG_EXPN_DATA_INLINE => {
+                let expn_data = Decodable::decode(self)?;
+                recover_from_expn_data(
+                    self, expn_data, AbsoluteBytePos::new(self.opaque.position())
                 )
             }
-            TAG_EXPANSION_INFO_SHORTHAND => {
+            TAG_EXPN_DATA_SHORTHAND => {
                 let pos = AbsoluteBytePos::decode(self)?;
-                let cached_ctxt = self.synthetic_expansion_infos.borrow().get(&pos).cloned();
+                let cached_ctxt = self.synthetic_syntax_contexts.borrow().get(&pos).cloned();
                 if let Some(ctxt) = cached_ctxt {
                     Span::new(lo, hi, ctxt)
                 } else {
-                    let expn_info =
-                        self.with_position(pos.to_usize(), |this| ExpnInfo::decode(this))?;
-                    recover_from_expn_info(self, expn_info, pos)
+                    let expn_data =
+                        self.with_position(pos.to_usize(), |this| ExpnData::decode(this))?;
+                    recover_from_expn_data(self, expn_data, pos)
                 }
             }
             _ => {
@@ -725,7 +725,7 @@ struct CacheEncoder<'a, 'tcx, E: ty_codec::TyEncoder> {
     encoder: &'a mut E,
     type_shorthands: FxHashMap<Ty<'tcx>, usize>,
     predicate_shorthands: FxHashMap<ty::Predicate<'tcx>, usize>,
-    expn_info_shorthands: FxHashMap<ExpnId, AbsoluteBytePos>,
+    expn_data_shorthands: FxHashMap<ExpnId, AbsoluteBytePos>,
     interpret_allocs: FxHashMap<interpret::AllocId, usize>,
     interpret_allocs_inverse: Vec<interpret::AllocId>,
     source_map: CachingSourceMapView<'tcx>,
@@ -817,17 +817,17 @@ where
         len.encode(self)?;
 
         if span_data.ctxt == SyntaxContext::root() {
-            TAG_NO_EXPANSION_INFO.encode(self)
+            TAG_NO_EXPN_DATA.encode(self)
         } else {
-            let (expn_id, expn_info) = span_data.ctxt.outer_expn_with_info();
-            if let Some(pos) = self.expn_info_shorthands.get(&expn_id).cloned() {
-                TAG_EXPANSION_INFO_SHORTHAND.encode(self)?;
+            let (expn_id, expn_data) = span_data.ctxt.outer_expn_with_data();
+            if let Some(pos) = self.expn_data_shorthands.get(&expn_id).cloned() {
+                TAG_EXPN_DATA_SHORTHAND.encode(self)?;
                 pos.encode(self)
             } else {
-                TAG_EXPANSION_INFO_INLINE.encode(self)?;
+                TAG_EXPN_DATA_INLINE.encode(self)?;
                 let pos = AbsoluteBytePos::new(self.position());
-                self.expn_info_shorthands.insert(expn_id, pos);
-                expn_info.encode(self)
+                self.expn_data_shorthands.insert(expn_id, pos);
+                expn_data.encode(self)
             }
         }
     }
diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs
index 240264a98220d..eec098426239c 100644
--- a/src/librustc_codegen_ssa/back/write.rs
+++ b/src/librustc_codegen_ssa/back/write.rs
@@ -1775,7 +1775,7 @@ impl SharedEmitterMain {
                     }
                 }
                 Ok(SharedEmitterMessage::InlineAsmError(cookie, msg)) => {
-                    sess.span_err(ExpnId::from_u32(cookie).expn_info().call_site, &msg)
+                    sess.span_err(ExpnId::from_u32(cookie).expn_data().call_site, &msg)
                 }
                 Ok(SharedEmitterMessage::AbortIfErrors) => {
                     sess.abort_if_errors();
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index 1bb05bda69f5b..90e467713968b 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -517,7 +517,7 @@ impl EarlyLintPass for UnusedParens {
                 // trigger in situations that macro authors shouldn't have to care about, e.g.,
                 // when a parenthesized token tree matched in one macro expansion is matched as
                 // an expression in another and used as a fn/method argument (Issue #47775)
-                if e.span.ctxt().outer_expn_info().call_site.from_expansion() {
+                if e.span.ctxt().outer_expn_data().call_site.from_expansion() {
                     return;
                 }
                 let msg = format!("{} argument", call_kind);
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 58e785ab8c253..2ca8771cda6a1 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -17,7 +17,7 @@ use syntax::edition::Edition;
 use syntax::ext::base::{self, Indeterminate, SpecialDerives};
 use syntax::ext::base::{MacroKind, SyntaxExtension};
 use syntax::ext::expand::{AstFragment, Invocation, InvocationKind};
-use syntax::ext::hygiene::{self, ExpnId, ExpnInfo, ExpnKind};
+use syntax::ext::hygiene::{self, ExpnId, ExpnData, ExpnKind};
 use syntax::ext::tt::macro_rules;
 use syntax::feature_gate::{emit_feature_err, is_builtin_attr_name};
 use syntax::feature_gate::GateIssue;
@@ -97,7 +97,7 @@ impl<'a> base::Resolver for Resolver<'a> {
     }
 
     fn get_module_scope(&mut self, id: ast::NodeId) -> ExpnId {
-        let expn_id = ExpnId::fresh(Some(ExpnInfo::default(
+        let expn_id = ExpnId::fresh(Some(ExpnData::default(
             ExpnKind::Macro(MacroKind::Attr, sym::test_case), DUMMY_SP, self.session.edition()
         )));
         let module = self.module_map[&self.definitions.local_def_id(id)];
@@ -185,8 +185,8 @@ impl<'a> base::Resolver for Resolver<'a> {
         let (ext, res) = self.smart_resolve_macro_path(path, kind, parent_scope, force)?;
 
         let span = invoc.span();
-        invoc.expansion_data.id.set_expn_info(
-            ext.expn_info(parent_scope.expansion, span, fast_print_path(path))
+        invoc.expansion_data.id.set_expn_data(
+            ext.expn_data(parent_scope.expansion, span, fast_print_path(path))
         );
 
         if let Res::Def(_, def_id) = res {
@@ -302,7 +302,7 @@ impl<'a> Resolver<'a> {
 
         // Possibly apply the macro helper hack
         if kind == Some(MacroKind::Bang) && path.len() == 1 &&
-           path[0].ident.span.ctxt().outer_expn_info().local_inner_macros {
+           path[0].ident.span.ctxt().outer_expn_data().local_inner_macros {
             let root = Ident::new(kw::DollarCrate, path[0].ident.span);
             path.insert(0, Segment::from_ident(root));
         }
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 734b566b3ad1d..fb1bf4d7160e7 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -15,7 +15,7 @@ use crate::tokenstream::{self, TokenStream, TokenTree};
 use errors::{DiagnosticBuilder, DiagnosticId};
 use smallvec::{smallvec, SmallVec};
 use syntax_pos::{FileName, Span, MultiSpan, DUMMY_SP};
-use syntax_pos::hygiene::{ExpnInfo, ExpnKind};
+use syntax_pos::hygiene::{ExpnData, ExpnKind};
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::{self, Lrc};
@@ -640,8 +640,8 @@ impl SyntaxExtension {
         SyntaxExtension::default(SyntaxExtensionKind::NonMacroAttr { mark_used }, edition)
     }
 
-    pub fn expn_info(&self, parent: ExpnId, call_site: Span, descr: Symbol) -> ExpnInfo {
-        ExpnInfo {
+    pub fn expn_data(&self, parent: ExpnId, call_site: Span, descr: Symbol) -> ExpnData {
+        ExpnData {
             kind: ExpnKind::Macro(self.macro_kind(), descr),
             parent,
             call_site,
@@ -708,7 +708,7 @@ pub struct ExpansionData {
 
 /// One of these is made during expansion and incrementally updated as we go;
 /// when a macro expansion occurs, the resulting nodes have the `backtrace()
-/// -> expn_info` of their expansion context stored into their span.
+/// -> expn_data` of their expansion context stored into their span.
 pub struct ExtCtxt<'a> {
     pub parse_sess: &'a parse::ParseSess,
     pub ecfg: expand::ExpansionConfig<'a>,
@@ -757,7 +757,7 @@ impl<'a> ExtCtxt<'a> {
     pub fn parse_sess(&self) -> &'a parse::ParseSess { self.parse_sess }
     pub fn cfg(&self) -> &ast::CrateConfig { &self.parse_sess.config }
     pub fn call_site(&self) -> Span {
-        self.current_expansion.id.expn_info().call_site
+        self.current_expansion.id.expn_data().call_site
     }
     pub fn backtrace(&self) -> SyntaxContext {
         SyntaxContext::root().apply_mark(self.current_expansion.id)
@@ -770,13 +770,13 @@ impl<'a> ExtCtxt<'a> {
         let mut ctxt = self.backtrace();
         let mut last_macro = None;
         loop {
-            let expn_info = ctxt.outer_expn_info();
+            let expn_data = ctxt.outer_expn_data();
             // Stop going up the backtrace once include! is encountered
-            if expn_info.is_root() || expn_info.kind.descr() == sym::include {
+            if expn_data.is_root() || expn_data.kind.descr() == sym::include {
                 break;
             }
-            ctxt = expn_info.call_site.ctxt();
-            last_macro = Some(expn_info.call_site);
+            ctxt = expn_data.call_site.ctxt();
+            last_macro = Some(expn_data.call_site);
         }
         last_macro
     }
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 4233d5c0a222e..e7deadbc9a043 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -5,7 +5,7 @@ use crate::source_map::respan;
 use crate::config::StripUnconfigured;
 use crate::ext::base::*;
 use crate::ext::proc_macro::collect_derives;
-use crate::ext::hygiene::{ExpnId, SyntaxContext, ExpnInfo, ExpnKind};
+use crate::ext::hygiene::{ExpnId, SyntaxContext, ExpnData, ExpnKind};
 use crate::ext::tt::macro_rules::annotate_err_with_kind;
 use crate::ext::placeholders::{placeholder, PlaceholderExpander};
 use crate::feature_gate::{self, Features, GateIssue, is_builtin_attr, emit_feature_err};
@@ -475,11 +475,11 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
         }
 
         if self.cx.current_expansion.depth > self.cx.ecfg.recursion_limit {
-            let info = self.cx.current_expansion.id.expn_info();
+            let expn_data = self.cx.current_expansion.id.expn_data();
             let suggested_limit = self.cx.ecfg.recursion_limit * 2;
-            let mut err = self.cx.struct_span_err(info.call_site,
+            let mut err = self.cx.struct_span_err(expn_data.call_site,
                 &format!("recursion limit reached while expanding the macro `{}`",
-                         info.kind.descr()));
+                         expn_data.kind.descr()));
             err.help(&format!(
                 "consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate",
                 suggested_limit));
@@ -796,20 +796,20 @@ struct InvocationCollector<'a, 'b> {
 
 impl<'a, 'b> InvocationCollector<'a, 'b> {
     fn collect(&mut self, fragment_kind: AstFragmentKind, kind: InvocationKind) -> AstFragment {
-        // Expansion info for all the collected invocations is set upon their resolution,
+        // Expansion data for all the collected invocations is set upon their resolution,
         // with exception of the derive container case which is not resolved and can get
-        // its expansion info immediately.
-        let expn_info = match &kind {
-            InvocationKind::DeriveContainer { item, .. } => Some(ExpnInfo {
+        // its expansion data immediately.
+        let expn_data = match &kind {
+            InvocationKind::DeriveContainer { item, .. } => Some(ExpnData {
                 parent: self.cx.current_expansion.id,
-                ..ExpnInfo::default(
+                ..ExpnData::default(
                     ExpnKind::Macro(MacroKind::Attr, sym::derive),
                     item.span(), self.cx.parse_sess.edition,
                 )
             }),
             _ => None,
         };
-        let expn_id = ExpnId::fresh(expn_info);
+        let expn_id = ExpnId::fresh(expn_data);
         self.invocations.push(Invocation {
             kind,
             fragment_kind,
diff --git a/src/libsyntax/ext/proc_macro_server.rs b/src/libsyntax/ext/proc_macro_server.rs
index d370431a5daef..1619fa6994198 100644
--- a/src/libsyntax/ext/proc_macro_server.rs
+++ b/src/libsyntax/ext/proc_macro_server.rs
@@ -362,7 +362,7 @@ pub(crate) struct Rustc<'a> {
 impl<'a> Rustc<'a> {
     pub fn new(cx: &'a ExtCtxt<'_>) -> Self {
         // No way to determine def location for a proc macro right now, so use call location.
-        let location = cx.current_expansion.id.expn_info().call_site;
+        let location = cx.current_expansion.id.expn_data().call_site;
         let to_span = |transparency| {
             location.with_ctxt(
                 SyntaxContext::root()
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index a1bcc455eb4cf..26f78b9c5c784 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -87,7 +87,7 @@ impl ParseSess {
             included_mod_stack: Lock::new(vec![]),
             source_map,
             buffered_lints: Lock::new(vec![]),
-            edition: ExpnId::root().expn_info().edition,
+            edition: ExpnId::root().expn_data().edition,
             ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
             param_attr_spans: Lock::new(Vec::new()),
             let_chains_spans: Lock::new(Vec::new()),
diff --git a/src/libsyntax/source_map.rs b/src/libsyntax/source_map.rs
index da7eb6add41a9..940687cb5d4e4 100644
--- a/src/libsyntax/source_map.rs
+++ b/src/libsyntax/source_map.rs
@@ -8,7 +8,7 @@
 //! information, source code snippets, etc.
 
 pub use syntax_pos::*;
-pub use syntax_pos::hygiene::{ExpnKind, ExpnInfo};
+pub use syntax_pos::hygiene::{ExpnKind, ExpnData};
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::stable_hasher::StableHasher;
@@ -29,15 +29,15 @@ mod tests;
 
 /// Returns the span itself if it doesn't come from a macro expansion,
 /// otherwise return the call site span up to the `enclosing_sp` by
-/// following the `expn_info` chain.
+/// following the `expn_data` chain.
 pub fn original_sp(sp: Span, enclosing_sp: Span) -> Span {
-    let expn_info1 = sp.ctxt().outer_expn_info();
-    let expn_info2 = enclosing_sp.ctxt().outer_expn_info();
-    if expn_info1.is_root() ||
-       !expn_info2.is_root() && expn_info1.call_site == expn_info2.call_site {
+    let expn_data1 = sp.ctxt().outer_expn_data();
+    let expn_data2 = enclosing_sp.ctxt().outer_expn_data();
+    if expn_data1.is_root() ||
+       !expn_data2.is_root() && expn_data1.call_site == expn_data2.call_site {
         sp
     } else {
-        original_sp(expn_info1.call_site, enclosing_sp)
+        original_sp(expn_data1.call_site, enclosing_sp)
     }
 }
 
diff --git a/src/libsyntax_ext/deriving/clone.rs b/src/libsyntax_ext/deriving/clone.rs
index 73df625d5ee60..d030ea4a56ebb 100644
--- a/src/libsyntax_ext/deriving/clone.rs
+++ b/src/libsyntax_ext/deriving/clone.rs
@@ -35,7 +35,7 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt<'_>,
             match annitem.node {
                 ItemKind::Struct(_, Generics { ref params, .. }) |
                 ItemKind::Enum(_, Generics { ref params, .. }) => {
-                    let container_id = cx.current_expansion.id.expn_info().parent;
+                    let container_id = cx.current_expansion.id.expn_data().parent;
                     if cx.resolver.has_derives(container_id, SpecialDerives::COPY) &&
                         !params.iter().any(|param| match param.kind {
                             ast::GenericParamKind::Type { .. } => true,
diff --git a/src/libsyntax_ext/deriving/cmp/eq.rs b/src/libsyntax_ext/deriving/cmp/eq.rs
index 1ef34a6800414..54027c600b4cd 100644
--- a/src/libsyntax_ext/deriving/cmp/eq.rs
+++ b/src/libsyntax_ext/deriving/cmp/eq.rs
@@ -13,7 +13,7 @@ pub fn expand_deriving_eq(cx: &mut ExtCtxt<'_>,
                           mitem: &MetaItem,
                           item: &Annotatable,
                           push: &mut dyn FnMut(Annotatable)) {
-    cx.resolver.add_derives(cx.current_expansion.id.expn_info().parent, SpecialDerives::EQ);
+    cx.resolver.add_derives(cx.current_expansion.id.expn_data().parent, SpecialDerives::EQ);
 
     let inline = cx.meta_word(span, sym::inline);
     let hidden = cx.meta_list_item_word(span, sym::hidden);
diff --git a/src/libsyntax_ext/deriving/cmp/partial_eq.rs b/src/libsyntax_ext/deriving/cmp/partial_eq.rs
index 76befc98591ef..91e1e80e4fbfa 100644
--- a/src/libsyntax_ext/deriving/cmp/partial_eq.rs
+++ b/src/libsyntax_ext/deriving/cmp/partial_eq.rs
@@ -13,7 +13,7 @@ pub fn expand_deriving_partial_eq(cx: &mut ExtCtxt<'_>,
                                   mitem: &MetaItem,
                                   item: &Annotatable,
                                   push: &mut dyn FnMut(Annotatable)) {
-    cx.resolver.add_derives(cx.current_expansion.id.expn_info().parent, SpecialDerives::PARTIAL_EQ);
+    cx.resolver.add_derives(cx.current_expansion.id.expn_data().parent, SpecialDerives::PARTIAL_EQ);
 
     // structures are equal if all fields are equal, and non equal, if
     // any fields are not equal or if the enum variants are different
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index 6b739e27eee89..55fb7677038ba 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -425,7 +425,7 @@ impl<'a> TraitDef<'a> {
                         return;
                     }
                 };
-                let container_id = cx.current_expansion.id.expn_info().parent;
+                let container_id = cx.current_expansion.id.expn_data().parent;
                 let is_always_copy =
                     cx.resolver.has_derives(container_id, SpecialDerives::COPY) &&
                     has_no_type_params;
diff --git a/src/libsyntax_ext/plugin_macro_defs.rs b/src/libsyntax_ext/plugin_macro_defs.rs
index b34a250881a31..dbfd8fe98f389 100644
--- a/src/libsyntax_ext/plugin_macro_defs.rs
+++ b/src/libsyntax_ext/plugin_macro_defs.rs
@@ -11,7 +11,7 @@ use syntax::source_map::respan;
 use syntax::symbol::sym;
 use syntax::tokenstream::*;
 use syntax_pos::{Span, DUMMY_SP};
-use syntax_pos::hygiene::{ExpnInfo, ExpnKind, MacroKind};
+use syntax_pos::hygiene::{ExpnData, ExpnKind, MacroKind};
 
 use std::mem;
 
@@ -43,7 +43,7 @@ pub fn inject(
 ) {
     if !named_exts.is_empty() {
         let mut extra_items = Vec::new();
-        let span = DUMMY_SP.fresh_expansion(ExpnInfo::allow_unstable(
+        let span = DUMMY_SP.fresh_expansion(ExpnData::allow_unstable(
             ExpnKind::Macro(MacroKind::Attr, sym::plugin), DUMMY_SP, edition,
             [sym::rustc_attrs][..].into(),
         ));
diff --git a/src/libsyntax_ext/proc_macro_harness.rs b/src/libsyntax_ext/proc_macro_harness.rs
index 9d8a8c17ba2d8..e772eaf834964 100644
--- a/src/libsyntax_ext/proc_macro_harness.rs
+++ b/src/libsyntax_ext/proc_macro_harness.rs
@@ -3,7 +3,7 @@ use std::mem;
 use smallvec::smallvec;
 use syntax::ast::{self, Ident};
 use syntax::attr;
-use syntax::source_map::{ExpnInfo, ExpnKind, respan};
+use syntax::source_map::{ExpnData, ExpnKind, respan};
 use syntax::ext::base::{ExtCtxt, MacroKind};
 use syntax::ext::expand::{AstFragment, ExpansionConfig};
 use syntax::ext::proc_macro::is_proc_macro_attr;
@@ -327,7 +327,7 @@ fn mk_decls(
     custom_attrs: &[ProcMacroDef],
     custom_macros: &[ProcMacroDef],
 ) -> P<ast::Item> {
-    let span = DUMMY_SP.fresh_expansion(ExpnInfo::allow_unstable(
+    let span = DUMMY_SP.fresh_expansion(ExpnData::allow_unstable(
         ExpnKind::Macro(MacroKind::Attr, sym::proc_macro), DUMMY_SP, cx.parse_sess.edition,
         [sym::rustc_attrs, sym::proc_macro_internals][..].into(),
     ));
diff --git a/src/libsyntax_ext/standard_library_imports.rs b/src/libsyntax_ext/standard_library_imports.rs
index c004124865223..8ca376341fcdb 100644
--- a/src/libsyntax_ext/standard_library_imports.rs
+++ b/src/libsyntax_ext/standard_library_imports.rs
@@ -2,7 +2,7 @@ use syntax::{ast, attr};
 use syntax::edition::Edition;
 use syntax::ext::hygiene::MacroKind;
 use syntax::ptr::P;
-use syntax::source_map::{ExpnInfo, ExpnKind, dummy_spanned, respan};
+use syntax::source_map::{ExpnData, ExpnKind, dummy_spanned, respan};
 use syntax::symbol::{Ident, Symbol, kw, sym};
 use syntax_pos::DUMMY_SP;
 
@@ -55,7 +55,7 @@ pub fn inject(
     // the prelude.
     let name = names[0];
 
-    let span = DUMMY_SP.fresh_expansion(ExpnInfo::allow_unstable(
+    let span = DUMMY_SP.fresh_expansion(ExpnData::allow_unstable(
         ExpnKind::Macro(MacroKind::Attr, sym::std_inject), DUMMY_SP, edition,
         [sym::prelude_import][..].into(),
     ));
diff --git a/src/libsyntax_ext/test_harness.rs b/src/libsyntax_ext/test_harness.rs
index 3fb1c1bd02240..4a6ea0ebf85e5 100644
--- a/src/libsyntax_ext/test_harness.rs
+++ b/src/libsyntax_ext/test_harness.rs
@@ -11,7 +11,7 @@ use syntax::feature_gate::Features;
 use syntax::mut_visit::{*, ExpectOne};
 use syntax::parse::ParseSess;
 use syntax::ptr::P;
-use syntax::source_map::{ExpnInfo, ExpnKind, dummy_spanned};
+use syntax::source_map::{ExpnData, ExpnKind, dummy_spanned};
 use syntax::symbol::{kw, sym, Symbol};
 use syntax_pos::{Span, DUMMY_SP};
 
@@ -268,7 +268,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
     //            #![main]
     //            test::test_main_static(&[..tests]);
     //        }
-    let sp = DUMMY_SP.fresh_expansion(ExpnInfo::allow_unstable(
+    let sp = DUMMY_SP.fresh_expansion(ExpnData::allow_unstable(
         ExpnKind::Macro(MacroKind::Attr, sym::test_case), DUMMY_SP, cx.ext_cx.parse_sess.edition,
         [sym::main, sym::test, sym::rustc_attrs][..].into(),
     ));
diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs
index 4d9496f94fbde..87d930f897afc 100644
--- a/src/libsyntax_pos/hygiene.rs
+++ b/src/libsyntax_pos/hygiene.rs
@@ -13,8 +13,8 @@
 //
 // This explains why `HygieneData`, `SyntaxContext` and `ExpnId` have interfaces
 // with a certain amount of redundancy in them. For example,
-// `SyntaxContext::outer_expn_info` combines `SyntaxContext::outer` and
-// `ExpnId::expn_info` so that two `HygieneData` accesses can be performed within
+// `SyntaxContext::outer_expn_data` combines `SyntaxContext::outer` and
+// `ExpnId::expn_data` so that two `HygieneData` accesses can be performed within
 // a single `HygieneData::with` call.
 //
 // It also explains why many functions appear in `HygieneData` and again in
@@ -76,8 +76,8 @@ pub enum Transparency {
 }
 
 impl ExpnId {
-    pub fn fresh(expn_info: Option<ExpnInfo>) -> Self {
-        HygieneData::with(|data| data.fresh_expn(expn_info))
+    pub fn fresh(expn_data: Option<ExpnData>) -> Self {
+        HygieneData::with(|data| data.fresh_expn(expn_data))
     }
 
     /// The ID of the theoretical expansion that generates freshly parsed, unexpanded AST.
@@ -97,16 +97,16 @@ impl ExpnId {
     }
 
     #[inline]
-    pub fn expn_info(self) -> ExpnInfo {
-        HygieneData::with(|data| data.expn_info(self).clone())
+    pub fn expn_data(self) -> ExpnData {
+        HygieneData::with(|data| data.expn_data(self).clone())
     }
 
     #[inline]
-    pub fn set_expn_info(self, info: ExpnInfo) {
+    pub fn set_expn_data(self, expn_data: ExpnData) {
         HygieneData::with(|data| {
-            let old_info = &mut data.expn_data[self.0 as usize];
-            assert!(old_info.is_none(), "expansion info is reset for an expansion ID");
-            *old_info = Some(info);
+            let old_expn_data = &mut data.expn_data[self.0 as usize];
+            assert!(old_expn_data.is_none(), "expansion data is reset for an expansion ID");
+            *old_expn_data = Some(expn_data);
         })
     }
 
@@ -124,9 +124,9 @@ impl ExpnId {
     #[inline]
     pub fn looks_like_proc_macro_derive(self) -> bool {
         HygieneData::with(|data| {
-            let expn_info = data.expn_info(self);
-            if let ExpnKind::Macro(MacroKind::Derive, _) = expn_info.kind {
-                return expn_info.default_transparency == Transparency::Opaque;
+            let expn_data = data.expn_data(self);
+            if let ExpnKind::Macro(MacroKind::Derive, _) = expn_data.kind {
+                return expn_data.default_transparency == Transparency::Opaque;
             }
             false
         })
@@ -135,10 +135,10 @@ impl ExpnId {
 
 #[derive(Debug)]
 crate struct HygieneData {
-    /// Each expansion should have an associated expansion info, but sometimes there's a delay
-    /// between creation of an expansion ID and obtaining its info (e.g. macros are collected
+    /// Each expansion should have an associated expansion data, but sometimes there's a delay
+    /// between creation of an expansion ID and obtaining its data (e.g. macros are collected
     /// first and then resolved later), so we use an `Option` here.
-    expn_data: Vec<Option<ExpnInfo>>,
+    expn_data: Vec<Option<ExpnData>>,
     syntax_context_data: Vec<SyntaxContextData>,
     syntax_context_map: FxHashMap<(SyntaxContext, ExpnId, Transparency), SyntaxContext>,
 }
@@ -146,7 +146,7 @@ crate struct HygieneData {
 impl HygieneData {
     crate fn new(edition: Edition) -> Self {
         HygieneData {
-            expn_data: vec![Some(ExpnInfo::default(ExpnKind::Root, DUMMY_SP, edition))],
+            expn_data: vec![Some(ExpnData::default(ExpnKind::Root, DUMMY_SP, edition))],
             syntax_context_data: vec![SyntaxContextData {
                 outer_expn: ExpnId::root(),
                 outer_transparency: Transparency::Opaque,
@@ -163,14 +163,14 @@ impl HygieneData {
         GLOBALS.with(|globals| f(&mut *globals.hygiene_data.borrow_mut()))
     }
 
-    fn fresh_expn(&mut self, expn_info: Option<ExpnInfo>) -> ExpnId {
-        self.expn_data.push(expn_info);
+    fn fresh_expn(&mut self, expn_data: Option<ExpnData>) -> ExpnId {
+        self.expn_data.push(expn_data);
         ExpnId(self.expn_data.len() as u32 - 1)
     }
 
-    fn expn_info(&self, expn_id: ExpnId) -> &ExpnInfo {
+    fn expn_data(&self, expn_id: ExpnId) -> &ExpnData {
         self.expn_data[expn_id.0 as usize].as_ref()
-            .expect("no expansion info for an expansion ID")
+            .expect("no expansion data for an expansion ID")
     }
 
     fn is_descendant_of(&self, mut expn_id: ExpnId, ancestor: ExpnId) -> bool {
@@ -178,7 +178,7 @@ impl HygieneData {
             if expn_id == ExpnId::root() {
                 return false;
             }
-            expn_id = self.expn_info(expn_id).parent;
+            expn_id = self.expn_data(expn_id).parent;
         }
         true
     }
@@ -221,7 +221,7 @@ impl HygieneData {
 
     fn walk_chain(&self, mut span: Span, to: SyntaxContext) -> Span {
         while span.from_expansion() && span.ctxt() != to {
-            span = self.expn_info(self.outer_expn(span.ctxt())).call_site;
+            span = self.expn_data(self.outer_expn(span.ctxt())).call_site;
         }
         span
     }
@@ -237,7 +237,7 @@ impl HygieneData {
     fn apply_mark(&mut self, ctxt: SyntaxContext, expn_id: ExpnId) -> SyntaxContext {
         assert_ne!(expn_id, ExpnId::root());
         self.apply_mark_with_transparency(
-            ctxt, expn_id, self.expn_info(expn_id).default_transparency
+            ctxt, expn_id, self.expn_data(expn_id).default_transparency
         )
     }
 
@@ -248,7 +248,7 @@ impl HygieneData {
             return self.apply_mark_internal(ctxt, expn_id, transparency);
         }
 
-        let call_site_ctxt = self.expn_info(expn_id).call_site.ctxt();
+        let call_site_ctxt = self.expn_data(expn_id).call_site.ctxt();
         let mut call_site_ctxt = if transparency == Transparency::SemiTransparent {
             self.modern(call_site_ctxt)
         } else {
@@ -540,20 +540,20 @@ impl SyntaxContext {
         HygieneData::with(|data| data.outer_expn(self))
     }
 
-    /// `ctxt.outer_expn_info()` is equivalent to but faster than
-    /// `ctxt.outer_expn().expn_info()`.
+    /// `ctxt.outer_expn_data()` is equivalent to but faster than
+    /// `ctxt.outer_expn().expn_data()`.
     #[inline]
-    pub fn outer_expn_info(self) -> ExpnInfo {
-        HygieneData::with(|data| data.expn_info(data.outer_expn(self)).clone())
+    pub fn outer_expn_data(self) -> ExpnData {
+        HygieneData::with(|data| data.expn_data(data.outer_expn(self)).clone())
     }
 
-    /// `ctxt.outer_expn_with_info()` is equivalent to but faster than
-    /// `{ let outer = ctxt.outer_expn(); (outer, outer.expn_info()) }`.
+    /// `ctxt.outer_expn_with_data()` is equivalent to but faster than
+    /// `{ let outer = ctxt.outer_expn(); (outer, outer.expn_data()) }`.
     #[inline]
-    pub fn outer_expn_with_info(self) -> (ExpnId, ExpnInfo) {
+    pub fn outer_expn_with_data(self) -> (ExpnId, ExpnData) {
         HygieneData::with(|data| {
             let outer = data.outer_expn(self);
-            (outer, data.expn_info(outer).clone())
+            (outer, data.expn_data(outer).clone())
         })
     }
 
@@ -574,9 +574,9 @@ impl Span {
     /// other compiler-generated code to set per-span properties like allowed unstable features.
     /// The returned span belongs to the created expansion and has the new properties,
     /// but its location is inherited from the current span.
-    pub fn fresh_expansion(self, expn_info: ExpnInfo) -> Span {
+    pub fn fresh_expansion(self, expn_data: ExpnData) -> Span {
         HygieneData::with(|data| {
-            let expn_id = data.fresh_expn(Some(expn_info));
+            let expn_id = data.fresh_expn(Some(expn_data));
             self.with_ctxt(data.apply_mark(SyntaxContext::root(), expn_id))
         })
     }
@@ -585,7 +585,7 @@ impl Span {
 /// A subset of properties from both macro definition and macro call available through global data.
 /// Avoid using this if you have access to the original definition or call structures.
 #[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
-pub struct ExpnInfo {
+pub struct ExpnData {
     // --- The part unique to each expansion.
     /// The kind of this expansion - macro or compiler desugaring.
     pub kind: ExpnKind,
@@ -598,7 +598,7 @@ pub struct ExpnInfo {
     /// `foo!()` invoked `bar!()` internally, and there was an
     /// expression inside `bar!`; the call_site of the expression in
     /// the expansion would point to the `bar!` invocation; that
-    /// call_site span would have its own ExpnInfo, with the call_site
+    /// call_site span would have its own ExpnData, with the call_site
     /// pointing to the `foo!` invocation.
     pub call_site: Span,
 
@@ -609,7 +609,7 @@ pub struct ExpnInfo {
     /// The span of the macro definition (possibly dummy).
     /// This span serves only informational purpose and is not used for resolution.
     pub def_site: Span,
-    /// Transparency used by `apply_mark` for the expansion with this expansion info by default.
+    /// Transparency used by `apply_mark` for the expansion with this expansion data by default.
     pub default_transparency: Transparency,
     /// List of #[unstable]/feature-gated features that the macro is allowed to use
     /// internally without forcing the whole crate to opt-in
@@ -625,10 +625,10 @@ pub struct ExpnInfo {
     pub edition: Edition,
 }
 
-impl ExpnInfo {
-    /// Constructs an expansion info with default properties.
-    pub fn default(kind: ExpnKind, call_site: Span, edition: Edition) -> ExpnInfo {
-        ExpnInfo {
+impl ExpnData {
+    /// Constructs expansion data with default properties.
+    pub fn default(kind: ExpnKind, call_site: Span, edition: Edition) -> ExpnData {
+        ExpnData {
             kind,
             parent: ExpnId::root(),
             call_site,
@@ -642,10 +642,10 @@ impl ExpnInfo {
     }
 
     pub fn allow_unstable(kind: ExpnKind, call_site: Span, edition: Edition,
-                          allow_internal_unstable: Lrc<[Symbol]>) -> ExpnInfo {
-        ExpnInfo {
+                          allow_internal_unstable: Lrc<[Symbol]>) -> ExpnData {
+        ExpnData {
             allow_internal_unstable: Some(allow_internal_unstable),
-            ..ExpnInfo::default(kind, call_site, edition)
+            ..ExpnData::default(kind, call_site, edition)
         }
     }
 
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index ae538677a3aac..aa36fe27d8ec4 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -21,7 +21,7 @@ use rustc_serialize::{Encodable, Decodable, Encoder, Decoder};
 pub mod edition;
 use edition::Edition;
 pub mod hygiene;
-pub use hygiene::{ExpnId, SyntaxContext, ExpnInfo, ExpnKind, MacroKind, DesugaringKind};
+pub use hygiene::{ExpnId, SyntaxContext, ExpnData, ExpnKind, MacroKind, DesugaringKind};
 
 mod span_encoding;
 pub use span_encoding::{Span, DUMMY_SP};
@@ -353,20 +353,20 @@ impl Span {
     /// Returns the source span -- this is either the supplied span, or the span for
     /// the macro callsite that expanded to it.
     pub fn source_callsite(self) -> Span {
-        let expn_info = self.ctxt().outer_expn_info();
-        if !expn_info.is_root() { expn_info.call_site.source_callsite() } else { self }
+        let expn_data = self.ctxt().outer_expn_data();
+        if !expn_data.is_root() { expn_data.call_site.source_callsite() } else { self }
     }
 
     /// The `Span` for the tokens in the previous macro expansion from which `self` was generated,
     /// if any.
     pub fn parent(self) -> Option<Span> {
-        let expn_info = self.ctxt().outer_expn_info();
-        if !expn_info.is_root() { Some(expn_info.call_site) } else { None }
+        let expn_data = self.ctxt().outer_expn_data();
+        if !expn_data.is_root() { Some(expn_data.call_site) } else { None }
     }
 
     /// Edition of the crate from which this span came.
     pub fn edition(self) -> edition::Edition {
-        self.ctxt().outer_expn_info().edition
+        self.ctxt().outer_expn_data().edition
     }
 
     #[inline]
@@ -382,22 +382,22 @@ impl Span {
     /// Returns the source callee.
     ///
     /// Returns `None` if the supplied span has no expansion trace,
-    /// else returns the `ExpnInfo` for the macro definition
+    /// else returns the `ExpnData` for the macro definition
     /// corresponding to the source callsite.
-    pub fn source_callee(self) -> Option<ExpnInfo> {
-        fn source_callee(expn_info: ExpnInfo) -> ExpnInfo {
-            let next_expn_info = expn_info.call_site.ctxt().outer_expn_info();
-            if !next_expn_info.is_root() { source_callee(next_expn_info) } else { expn_info }
+    pub fn source_callee(self) -> Option<ExpnData> {
+        fn source_callee(expn_data: ExpnData) -> ExpnData {
+            let next_expn_data = expn_data.call_site.ctxt().outer_expn_data();
+            if !next_expn_data.is_root() { source_callee(next_expn_data) } else { expn_data }
         }
-        let expn_info = self.ctxt().outer_expn_info();
-        if !expn_info.is_root() { Some(source_callee(expn_info)) } else { None }
+        let expn_data = self.ctxt().outer_expn_data();
+        if !expn_data.is_root() { Some(source_callee(expn_data)) } else { None }
     }
 
     /// Checks if a span is "internal" to a macro in which `#[unstable]`
     /// items can be used (that is, a macro marked with
     /// `#[allow_internal_unstable]`).
     pub fn allows_unstable(&self, feature: Symbol) -> bool {
-        self.ctxt().outer_expn_info().allow_internal_unstable.map_or(false, |features| {
+        self.ctxt().outer_expn_data().allow_internal_unstable.map_or(false, |features| {
             features.iter().any(|&f| {
                 f == feature || f == sym::allow_internal_unstable_backcompat_hack
             })
@@ -406,7 +406,7 @@ impl Span {
 
     /// Checks if this span arises from a compiler desugaring of kind `kind`.
     pub fn is_desugaring(&self, kind: DesugaringKind) -> bool {
-        match self.ctxt().outer_expn_info().kind {
+        match self.ctxt().outer_expn_data().kind {
             ExpnKind::Desugaring(k) => k == kind,
             _ => false,
         }
@@ -415,7 +415,7 @@ impl Span {
     /// Returns the compiler desugaring that created this span, or `None`
     /// if this span is not from a desugaring.
     pub fn desugaring_kind(&self) -> Option<DesugaringKind> {
-        match self.ctxt().outer_expn_info().kind {
+        match self.ctxt().outer_expn_data().kind {
             ExpnKind::Desugaring(k) => Some(k),
             _ => None
         }
@@ -425,20 +425,20 @@ impl Span {
     /// can be used without triggering the `unsafe_code` lint
     //  (that is, a macro marked with `#[allow_internal_unsafe]`).
     pub fn allows_unsafe(&self) -> bool {
-        self.ctxt().outer_expn_info().allow_internal_unsafe
+        self.ctxt().outer_expn_data().allow_internal_unsafe
     }
 
     pub fn macro_backtrace(mut self) -> Vec<MacroBacktrace> {
         let mut prev_span = DUMMY_SP;
         let mut result = vec![];
         loop {
-            let info = self.ctxt().outer_expn_info();
-            if info.is_root() {
+            let expn_data = self.ctxt().outer_expn_data();
+            if expn_data.is_root() {
                 break;
             }
             // Don't print recursive invocations.
-            if !info.call_site.source_equal(&prev_span) {
-                let (pre, post) = match info.kind {
+            if !expn_data.call_site.source_equal(&prev_span) {
+                let (pre, post) = match expn_data.kind {
                     ExpnKind::Root => break,
                     ExpnKind::Desugaring(..) => ("desugaring of ", ""),
                     ExpnKind::Macro(macro_kind, _) => match macro_kind {
@@ -448,14 +448,14 @@ impl Span {
                     }
                 };
                 result.push(MacroBacktrace {
-                    call_site: info.call_site,
-                    macro_decl_name: format!("{}{}{}", pre, info.kind.descr(), post),
-                    def_site_span: info.def_site,
+                    call_site: expn_data.call_site,
+                    macro_decl_name: format!("{}{}{}", pre, expn_data.kind.descr(), post),
+                    def_site_span: expn_data.def_site,
                 });
             }
 
             prev_span = self;
-            self = info.call_site;
+            self = expn_data.call_site;
         }
         result
     }

From c76277340e3e5e8d6aca9c926c45cac3484eb5f8 Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Thu, 15 Aug 2019 20:47:15 +0300
Subject: [PATCH 33/35] resolve: `ParentScope::default` ->
 `ParentScope::module`

---
 src/librustc_resolve/build_reduced_graph.rs      |  2 +-
 src/librustc_resolve/late.rs                     |  2 +-
 src/librustc_resolve/lib.rs                      | 10 ++++++----
 src/librustc_resolve/macros.rs                   |  2 +-
 src/librustdoc/passes/collect_intra_doc_links.rs |  2 +-
 5 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index c42a933a954a9..539e4a301e012 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -166,7 +166,7 @@ impl<'a> Resolver<'a> {
         let def_id = module.def_id().unwrap();
         for child in self.cstore.item_children_untracked(def_id, self.session) {
             let child = child.map_id(|_| panic!("unexpected id"));
-            BuildReducedGraphVisitor { parent_scope: ParentScope::default(module), r: self }
+            BuildReducedGraphVisitor { parent_scope: ParentScope::module(module), r: self }
                 .build_reduced_graph_for_external_crate_res(child);
         }
         module.populated.set(true)
diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index d97ee61d839a2..ffdfd85002bca 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -509,7 +509,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         // During late resolution we only track the module component of the parent scope,
         // although it may be useful to track other components as well for diagnostics.
         let graph_root = resolver.graph_root;
-        let parent_scope = ParentScope::default(graph_root);
+        let parent_scope = ParentScope::module(graph_root);
         LateResolutionVisitor {
             r: resolver,
             parent_scope,
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 2b55f9dc79d08..9b5eb51eb582d 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -140,7 +140,9 @@ pub struct ParentScope<'a> {
 }
 
 impl<'a> ParentScope<'a> {
-    pub fn default(module: Module<'a>) -> ParentScope<'a> {
+    /// Creates a parent scope with the passed argument used as the module scope component,
+    /// and other scope components set to default empty values.
+    pub fn module(module: Module<'a>) -> ParentScope<'a> {
         ParentScope {
             module,
             expansion: ExpnId::root(),
@@ -1017,7 +1019,7 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> {
             segments,
         };
 
-        let parent_scope = &ParentScope::default(self.graph_root);
+        let parent_scope = &ParentScope::module(self.graph_root);
         let res = match self.resolve_ast_path(&path, ns, parent_scope) {
             Ok(res) => res,
             Err((span, error)) => {
@@ -1090,7 +1092,7 @@ impl<'a> Resolver<'a> {
         }
 
         let mut invocation_parent_scopes = FxHashMap::default();
-        invocation_parent_scopes.insert(ExpnId::root(), ParentScope::default(graph_root));
+        invocation_parent_scopes.insert(ExpnId::root(), ParentScope::module(graph_root));
 
         let mut macro_defs = FxHashMap::default();
         macro_defs.insert(ExpnId::root(), root_def_id);
@@ -2671,7 +2673,7 @@ impl<'a> Resolver<'a> {
             let def_id = self.definitions.local_def_id(module_id);
             self.module_map.get(&def_id).copied().unwrap_or(self.graph_root)
         });
-        let parent_scope = &ParentScope::default(module);
+        let parent_scope = &ParentScope::module(module);
         let res = self.resolve_ast_path(&path, ns, parent_scope).map_err(|_| ())?;
         Ok((path, res))
     }
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 2ca8771cda6a1..079145e816cd5 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -101,7 +101,7 @@ impl<'a> base::Resolver for Resolver<'a> {
             ExpnKind::Macro(MacroKind::Attr, sym::test_case), DUMMY_SP, self.session.edition()
         )));
         let module = self.module_map[&self.definitions.local_def_id(id)];
-        self.invocation_parent_scopes.insert(expn_id, ParentScope::default(module));
+        self.invocation_parent_scopes.insert(expn_id, ParentScope::module(module));
         self.definitions.set_invocation_parent(expn_id, module.def_id().unwrap().index);
         expn_id
     }
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 5767b5b3b46a5..c73c46472d804 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -432,7 +432,7 @@ fn macro_resolve(cx: &DocContext<'_>, path_str: &str) -> Option<Res> {
     let path = ast::Path::from_ident(Ident::from_str(path_str));
     cx.enter_resolver(|resolver| {
         if let Ok((Some(ext), res)) = resolver.resolve_macro_path(
-            &path, None, &ParentScope::default(resolver.graph_root), false, false
+            &path, None, &ParentScope::module(resolver.graph_root), false, false
         ) {
             if let SyntaxExtensionKind::LegacyBang { .. } = ext.kind {
                 return Some(res.map_id(|_| panic!("unexpected id")));

From fbf1efb949b9d76b4964b7b6a7a606de116ecb46 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Thu, 15 Aug 2019 11:46:52 -0700
Subject: [PATCH 34/35] Do not suggest `try_into` for base types inside of
 macro expansions

---
 src/librustc_typeck/check/demand.rs                   |  4 ++++
 .../ui/suggestions/dont-suggest-try_into-in-macros.rs |  3 +++
 .../dont-suggest-try_into-in-macros.stderr            | 11 +++++++++++
 3 files changed, 18 insertions(+)
 create mode 100644 src/test/ui/suggestions/dont-suggest-try_into-in-macros.rs
 create mode 100644 src/test/ui/suggestions/dont-suggest-try_into-in-macros.stderr

diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index ed25601208ad1..f3b56b31b775d 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -554,6 +554,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // FIXME(estebank): modify once we decide to suggest `as` casts
             return false;
         }
+        if !self.tcx.sess.source_map().span_to_filename(expr.span).is_real() {
+            // Ignore if span is from within a macro.
+            return false;
+        }
 
         // If casting this expression to a given numeric type would be appropriate in case of a type
         // mismatch.
diff --git a/src/test/ui/suggestions/dont-suggest-try_into-in-macros.rs b/src/test/ui/suggestions/dont-suggest-try_into-in-macros.rs
new file mode 100644
index 0000000000000..d625199c937c7
--- /dev/null
+++ b/src/test/ui/suggestions/dont-suggest-try_into-in-macros.rs
@@ -0,0 +1,3 @@
+fn main() {
+    assert_eq!(10u64, 10usize); //~ ERROR mismatched types
+}
diff --git a/src/test/ui/suggestions/dont-suggest-try_into-in-macros.stderr b/src/test/ui/suggestions/dont-suggest-try_into-in-macros.stderr
new file mode 100644
index 0000000000000..f04306997a9ed
--- /dev/null
+++ b/src/test/ui/suggestions/dont-suggest-try_into-in-macros.stderr
@@ -0,0 +1,11 @@
+error[E0308]: mismatched types
+  --> $DIR/dont-suggest-try_into-in-macros.rs:2:5
+   |
+LL |     assert_eq!(10u64, 10usize);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected u64, found usize
+   |
+   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.

From e046a7af49d37b0179078c83387925f8abc2555f Mon Sep 17 00:00:00 2001
From: Jens Hausdorf <mail@jens-hausdorf.de>
Date: Thu, 15 Aug 2019 22:16:59 +0200
Subject: [PATCH 35/35] Fix typo in DoubleEndedIterator::nth_back doc

---
 src/libcore/iter/traits/double_ended.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libcore/iter/traits/double_ended.rs b/src/libcore/iter/traits/double_ended.rs
index 8e5bc9b664cf0..006b243ca42aa 100644
--- a/src/libcore/iter/traits/double_ended.rs
+++ b/src/libcore/iter/traits/double_ended.rs
@@ -69,7 +69,7 @@ pub trait DoubleEndedIterator: Iterator {
     /// Returns the `n`th element from the end of the iterator.
     ///
     /// This is essentially the reversed version of [`nth`]. Although like most indexing
-    /// operations, the count starts from zero, so `nth_back(0)` returns the first value fro
+    /// operations, the count starts from zero, so `nth_back(0)` returns the first value from
     /// the end, `nth_back(1)` the second, and so on.
     ///
     /// Note that all elements between the end and the returned element will be