about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2021-04-04 17:51:31 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2021-04-04 17:51:41 +0300
commitb96584485a43c561d90eb262651ecb87d1d98d2a (patch)
tree1952d4a71c2d9496c568b991f4d6b5e323022828
parentfbf1bec48228a5c6c16073319cd4c9a54ec28c9f (diff)
downloadrust-b96584485a43c561d90eb262651ecb87d1d98d2a.tar.gz
rust-b96584485a43c561d90eb262651ecb87d1d98d2a.zip
resolve: Stable order for derive helper attributes
-rw-r--r--compiler/rustc_resolve/src/lib.rs2
-rw-r--r--compiler/rustc_resolve/src/macros.rs13
2 files changed, 9 insertions, 6 deletions
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 9488ce14a54..d474e990211 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -853,7 +853,7 @@ enum BuiltinMacroState {
 
 struct DeriveData {
     resolutions: DeriveResolutions,
-    helper_attrs: Vec<Ident>,
+    helper_attrs: Vec<(usize, Ident)>,
     has_derive_copy: bool,
 }
 
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 567a99e4abf..10e27f33c29 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -376,7 +376,7 @@ impl<'a> ResolverExpand for Resolver<'a> {
             has_derive_copy: false,
         });
         let parent_scope = self.invocation_parent_scopes[&expn_id];
-        for (path, opt_ext) in &mut entry.resolutions {
+        for (i, (path, opt_ext)) in entry.resolutions.iter_mut().enumerate() {
             if opt_ext.is_none() {
                 *opt_ext = Some(
                     match self.resolve_macro_path(
@@ -391,7 +391,9 @@ impl<'a> ResolverExpand for Resolver<'a> {
                                 let last_seg = path.segments.last().unwrap();
                                 let span = last_seg.ident.span.normalize_to_macros_2_0();
                                 entry.helper_attrs.extend(
-                                    ext.helper_attrs.iter().map(|name| Ident::new(*name, span)),
+                                    ext.helper_attrs
+                                        .iter()
+                                        .map(|name| (i, Ident::new(*name, span))),
                                 );
                             }
                             entry.has_derive_copy |= ext.builtin_name == Some(sym::Copy);
@@ -407,9 +409,10 @@ impl<'a> ResolverExpand for Resolver<'a> {
                 );
             }
         }
-        // If we get to here, then `derive_data` for the given `expn_id` will only be accessed by
-        // `take_derive_resolutions` later, so we can steal `helper_attrs` instead of cloning them.
-        self.helper_attrs.insert(expn_id, mem::take(&mut entry.helper_attrs));
+        // Sort helpers in a stable way independent from the derive resolution order.
+        entry.helper_attrs.sort_by_key(|(i, _)| *i);
+        self.helper_attrs
+            .insert(expn_id, entry.helper_attrs.iter().map(|(_, ident)| *ident).collect());
         // Mark this derive as having `Copy` either if it has `Copy` itself or if its parent derive
         // has `Copy`, to support cases like `#[derive(Clone, Copy)] #[derive(Debug)]`.
         if entry.has_derive_copy || self.has_derive_copy(parent_scope.expansion) {