diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index 0f4441d020b..27274f706e1 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -491,6 +491,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
             let fragment_kind = invoc.fragment_kind;
             let (expanded_fragment, new_invocations) = match self.expand_invoc(invoc, &ext.kind) {
                 ExpandResult::Ready(fragment) => {
+                    let mut derive_invocations = Vec::new();
                     let derive_placeholders = self
                         .cx
                         .resolver
@@ -512,14 +513,14 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                                 _ => unreachable!(),
                             };
 
-                            invocations.reserve(derives.len());
+                            derive_invocations.reserve(derives.len());
                             derives
                                 .into_iter()
                                 .map(|(path, _exts)| {
                                     // FIXME: Consider using the derive resolutions (`_exts`)
                                     // instead of enqueuing the derives to be resolved again later.
                                     let expn_id = ExpnId::fresh(None);
-                                    invocations.push((
+                                    derive_invocations.push((
                                         Invocation {
                                             kind: InvocationKind::Derive {
                                                 path,
@@ -546,7 +547,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                         })
                         .unwrap_or_default();
 
-                    self.collect_invocations(fragment, &derive_placeholders)
+                    let (fragment, collected_invocations) =
+                        self.collect_invocations(fragment, &derive_placeholders);
+                    // We choose to expand any derive invocations associated with this macro invocation
+                    // *before* any macro invocations collected from the output fragment
+                    derive_invocations.extend(collected_invocations);
+                    (fragment, derive_invocations)
                 }
                 ExpandResult::Retry(invoc) => {
                     if force {
diff --git a/src/test/ui/macros/builtin-std-paths-fail.stderr b/src/test/ui/macros/builtin-std-paths-fail.stderr
index 4f1a76b0d6e..ba626101190 100644
--- a/src/test/ui/macros/builtin-std-paths-fail.stderr
+++ b/src/test/ui/macros/builtin-std-paths-fail.stderr
@@ -10,6 +10,18 @@ error[E0433]: failed to resolve: could not find `RustcDecodable` in `core`
 LL |     core::RustcDecodable,
    |           ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `core`
 
+error[E0433]: failed to resolve: could not find `RustcDecodable` in `core`
+  --> $DIR/builtin-std-paths-fail.rs:2:11
+   |
+LL |     core::RustcDecodable,
+   |           ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `core`
+
+error[E0433]: failed to resolve: could not find `RustcDecodable` in `core`
+  --> $DIR/builtin-std-paths-fail.rs:4:11
+   |
+LL |     core::RustcDecodable,
+   |           ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `core`
+
 error[E0433]: failed to resolve: could not find `bench` in `core`
   --> $DIR/builtin-std-paths-fail.rs:7:9
    |
@@ -34,17 +46,17 @@ error[E0433]: failed to resolve: could not find `test` in `core`
 LL | #[core::test]
    |         ^^^^ could not find `test` in `core`
 
-error[E0433]: failed to resolve: could not find `RustcDecodable` in `core`
-  --> $DIR/builtin-std-paths-fail.rs:4:11
+error[E0433]: failed to resolve: could not find `RustcDecodable` in `std`
+  --> $DIR/builtin-std-paths-fail.rs:14:10
    |
-LL |     core::RustcDecodable,
-   |           ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `core`
+LL |     std::RustcDecodable,
+   |          ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `std`
 
-error[E0433]: failed to resolve: could not find `RustcDecodable` in `core`
-  --> $DIR/builtin-std-paths-fail.rs:2:11
+error[E0433]: failed to resolve: could not find `RustcDecodable` in `std`
+  --> $DIR/builtin-std-paths-fail.rs:16:10
    |
-LL |     core::RustcDecodable,
-   |           ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `core`
+LL |     std::RustcDecodable,
+   |          ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `std`
 
 error[E0433]: failed to resolve: could not find `RustcDecodable` in `std`
   --> $DIR/builtin-std-paths-fail.rs:14:10
@@ -82,18 +94,6 @@ error[E0433]: failed to resolve: could not find `test` in `std`
 LL | #[std::test]
    |        ^^^^ could not find `test` in `std`
 
-error[E0433]: failed to resolve: could not find `RustcDecodable` in `std`
-  --> $DIR/builtin-std-paths-fail.rs:16:10
-   |
-LL |     std::RustcDecodable,
-   |          ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `std`
-
-error[E0433]: failed to resolve: could not find `RustcDecodable` in `std`
-  --> $DIR/builtin-std-paths-fail.rs:14:10
-   |
-LL |     std::RustcDecodable,
-   |          ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `std`
-
 error: aborting due to 16 previous errors
 
 For more information about this error, try `rustc --explain E0433`.
diff --git a/src/test/ui/proc-macro/attribute-after-derive.stdout b/src/test/ui/proc-macro/attribute-after-derive.stdout
index 11f49235327..d0b66551919 100644
--- a/src/test/ui/proc-macro/attribute-after-derive.stdout
+++ b/src/test/ui/proc-macro/attribute-after-derive.stdout
@@ -99,22 +99,6 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [
         span: $DIR/attribute-after-derive.rs:18:1: 21:2 (#0),
     },
 ]
-PRINT-ATTR INPUT (DISPLAY): struct DeriveAttribute { }
-PRINT-ATTR INPUT (DEBUG): TokenStream [
-    Ident {
-        ident: "struct",
-        span: $DIR/attribute-after-derive.rs:25:1: 28:2 (#0),
-    },
-    Ident {
-        ident: "DeriveAttribute",
-        span: $DIR/attribute-after-derive.rs:25:1: 28:2 (#0),
-    },
-    Group {
-        delimiter: Brace,
-        stream: TokenStream [],
-        span: $DIR/attribute-after-derive.rs:25:1: 28:2 (#0),
-    },
-]
 PRINT-DERIVE INPUT (DISPLAY): #[print_attr] struct DeriveAttribute { }
 PRINT-DERIVE INPUT (DEBUG): TokenStream [
     Punct {
@@ -146,3 +130,19 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [
         span: $DIR/attribute-after-derive.rs:25:1: 28:2 (#0),
     },
 ]
+PRINT-ATTR INPUT (DISPLAY): struct DeriveAttribute { }
+PRINT-ATTR INPUT (DEBUG): TokenStream [
+    Ident {
+        ident: "struct",
+        span: $DIR/attribute-after-derive.rs:25:1: 28:2 (#0),
+    },
+    Ident {
+        ident: "DeriveAttribute",
+        span: $DIR/attribute-after-derive.rs:25:1: 28:2 (#0),
+    },
+    Group {
+        delimiter: Brace,
+        stream: TokenStream [],
+        span: $DIR/attribute-after-derive.rs:25:1: 28:2 (#0),
+    },
+]
diff --git a/src/test/ui/proc-macro/auxiliary/multiple-derives.rs b/src/test/ui/proc-macro/auxiliary/multiple-derives.rs
new file mode 100644
index 00000000000..e3f6607b2ae
--- /dev/null
+++ b/src/test/ui/proc-macro/auxiliary/multiple-derives.rs
@@ -0,0 +1,22 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+
+macro_rules! make_derives {
+    ($($name:ident),*) => {
+        $(
+            #[proc_macro_derive($name)]
+            pub fn $name(input: TokenStream) -> TokenStream {
+                println!("Derive {}: {}", stringify!($name), input);
+                TokenStream::new()
+            }
+        )*
+    }
+}
+
+make_derives!(First, Second, Third, Fourth, Fifth);
diff --git a/src/test/ui/proc-macro/derive-expand-order.rs b/src/test/ui/proc-macro/derive-expand-order.rs
new file mode 100644
index 00000000000..0cf1ceb91de
--- /dev/null
+++ b/src/test/ui/proc-macro/derive-expand-order.rs
@@ -0,0 +1,14 @@
+// run-pass
+// aux-build:multiple-derives.rs
+
+extern crate multiple_derives;
+
+use multiple_derives::*;
+
+#[derive(First)]
+#[derive(Second)]
+#[derive(Third, Fourth)]
+#[derive(Fifth)]
+pub struct Foo {}
+
+fn main() {}
diff --git a/src/test/ui/proc-macro/derive-expand-order.stdout b/src/test/ui/proc-macro/derive-expand-order.stdout
new file mode 100644
index 00000000000..3ac1adf92c2
--- /dev/null
+++ b/src/test/ui/proc-macro/derive-expand-order.stdout
@@ -0,0 +1,5 @@
+Derive First: #[derive(Second)] #[derive(Third, Fourth)] #[derive(Fifth)] pub struct Foo { }
+Derive Second: #[derive(Third, Fourth)] #[derive(Fifth)] pub struct Foo { }
+Derive Third: #[derive(Fifth)] pub struct Foo { }
+Derive Fourth: #[derive(Fifth)] pub struct Foo { }
+Derive Fifth: pub struct Foo { }
diff --git a/src/test/ui/proc-macro/issue-36935.stderr b/src/test/ui/proc-macro/issue-36935.stderr
index 2b2e28fdb2f..079e134c6f8 100644
--- a/src/test/ui/proc-macro/issue-36935.stderr
+++ b/src/test/ui/proc-macro/issue-36935.stderr
@@ -1,11 +1,3 @@
-error: proc-macro derive panicked
-  --> $DIR/issue-36935.rs:6:20
-   |
-LL | #[derive(Identity, Panic)]
-   |                    ^^^^^
-   |
-   = help: message: panic-derive
-
 error[E0428]: the name `Baz` is defined multiple times
   --> $DIR/issue-36935.rs:7:1
    |
@@ -17,6 +9,14 @@ LL | struct Baz {
    |
    = note: `Baz` must be defined only once in the type namespace of this module
 
+error: proc-macro derive panicked
+  --> $DIR/issue-36935.rs:6:20
+   |
+LL | #[derive(Identity, Panic)]
+   |                    ^^^^^
+   |
+   = help: message: panic-derive
+
 error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0428`.
diff --git a/src/test/ui/union/union-derive.stderr b/src/test/ui/union/union-derive.stderr
index 919c6d5ceda..6ef72c901a5 100644
--- a/src/test/ui/union/union-derive.stderr
+++ b/src/test/ui/union/union-derive.stderr
@@ -1,26 +1,8 @@
 error: this trait cannot be derived for unions
-  --> $DIR/union-derive.rs:9:5
+  --> $DIR/union-derive.rs:4:5
    |
-LL |     Debug,
-   |     ^^^^^
-
-error: this trait cannot be derived for unions
-  --> $DIR/union-derive.rs:8:5
-   |
-LL |     Default,
-   |     ^^^^^^^
-
-error: this trait cannot be derived for unions
-  --> $DIR/union-derive.rs:7:5
-   |
-LL |     Hash,
-   |     ^^^^
-
-error: this trait cannot be derived for unions
-  --> $DIR/union-derive.rs:6:5
-   |
-LL |     Ord,
-   |     ^^^
+LL |     PartialEq,
+   |     ^^^^^^^^^
 
 error: this trait cannot be derived for unions
   --> $DIR/union-derive.rs:5:5
@@ -29,10 +11,28 @@ LL |     PartialOrd,
    |     ^^^^^^^^^^
 
 error: this trait cannot be derived for unions
-  --> $DIR/union-derive.rs:4:5
+  --> $DIR/union-derive.rs:6:5
    |
-LL |     PartialEq,
-   |     ^^^^^^^^^
+LL |     Ord,
+   |     ^^^
+
+error: this trait cannot be derived for unions
+  --> $DIR/union-derive.rs:7:5
+   |
+LL |     Hash,
+   |     ^^^^
+
+error: this trait cannot be derived for unions
+  --> $DIR/union-derive.rs:8:5
+   |
+LL |     Default,
+   |     ^^^^^^^
+
+error: this trait cannot be derived for unions
+  --> $DIR/union-derive.rs:9:5
+   |
+LL |     Debug,
+   |     ^^^^^
 
 error: aborting due to 6 previous errors