]> git.lizzy.rs Git - rust.git/commitdiff
resolve: Stable order for derive helper attributes
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>
Sun, 4 Apr 2021 14:51:31 +0000 (17:51 +0300)
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>
Sun, 4 Apr 2021 14:51:41 +0000 (17:51 +0300)
compiler/rustc_resolve/src/lib.rs
compiler/rustc_resolve/src/macros.rs

index 9488ce14a54ea6265439af077e3839d14fc6ce9b..d474e99021104e392249f4a09d79477ac0264f57 100644 (file)
@@ -853,7 +853,7 @@ enum BuiltinMacroState {
 
 struct DeriveData {
     resolutions: DeriveResolutions,
-    helper_attrs: Vec<Ident>,
+    helper_attrs: Vec<(usize, Ident)>,
     has_derive_copy: bool,
 }
 
index 567a99e4abf5aa3a914dc1be6f1c6874e8dc8375..10e27f33c29960776dc92d2f77233b8e5fb7e3d7 100644 (file)
@@ -376,7 +376,7 @@ fn resolve_derives(
             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 @@ fn resolve_derives(
                                 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 @@ fn resolve_derives(
                 );
             }
         }
-        // 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) {