From: Vadim Petrochenkov Date: Sun, 4 Apr 2021 14:51:31 +0000 (+0300) Subject: resolve: Stable order for derive helper attributes X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=b96584485a43c561d90eb262651ecb87d1d98d2a;p=rust.git resolve: Stable order for derive helper attributes --- 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, + 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 @@ 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) {