From 5ff00f96e62248e2e9fe8233ffd98e47bf3dfdc7 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 21 Feb 2023 11:35:19 +0100 Subject: [PATCH 1/7] Use DefIdMap instead of FxHashMap for impl_item_implementor_ids query. --- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_ty_utils/src/assoc.rs | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 8fe5586723d..fc4b3a2413a 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -757,7 +757,7 @@ rustc_queries! { /// /// The map returned for `tcx.impl_item_implementor_ids(impl_id)` would be ///`{ trait_f: impl_f, trait_g: impl_g }` - query impl_item_implementor_ids(impl_id: DefId) -> &'tcx FxHashMap { + query impl_item_implementor_ids(impl_id: DefId) -> &'tcx DefIdMap { arena_cache desc { |tcx| "comparing impl items against trait for `{}`", tcx.def_path_str(impl_id) } } diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index d4866b5dbdd..8312988ca3e 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -1,7 +1,6 @@ -use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; use rustc_hir::def::DefKind; -use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId}; use rustc_hir::definitions::DefPathData; use rustc_hir::intravisit::{self, Visitor}; use rustc_middle::ty::{self, DefIdTree, TyCtxt}; @@ -40,7 +39,7 @@ fn associated_items(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AssocItems { } } -fn impl_item_implementor_ids(tcx: TyCtxt<'_>, impl_id: DefId) -> FxHashMap { +fn impl_item_implementor_ids(tcx: TyCtxt<'_>, impl_id: DefId) -> DefIdMap { tcx.associated_items(impl_id) .in_definition_order() .filter_map(|item| item.trait_item_def_id.map(|trait_item| (trait_item, item.def_id))) From f0eadbafd429c32bf3362dedeb23287027bfe450 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 21 Feb 2023 12:07:17 +0100 Subject: [PATCH 2/7] Use LocalDefIdSet instead of FxHashSet for reachable_set query. --- compiler/rustc_codegen_ssa/src/back/symbol_export.rs | 4 ++-- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_middle/src/ty/query.rs | 2 +- compiler/rustc_passes/src/reachable.rs | 8 ++++---- src/tools/miri/src/bin/miri.rs | 5 ++++- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 067a3e167fe..32731a3024c 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -58,7 +58,7 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap< let mut reachable_non_generics: DefIdMap<_> = tcx .reachable_set(()) - .iter() + .items() .filter_map(|&def_id| { // We want to ignore some FFI functions that are not exposed from // this crate. Reachable FFI functions can be lumped into two @@ -136,7 +136,7 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap< }; (def_id.to_def_id(), info) }) - .collect(); + .into(); if let Some(id) = tcx.proc_macro_decls_static(()) { reachable_non_generics.insert( diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index fc4b3a2413a..743f4d9ca2a 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1113,7 +1113,7 @@ rustc_queries! { desc { "checking for private elements in public interfaces" } } - query reachable_set(_: ()) -> &'tcx FxHashSet { + query reachable_set(_: ()) -> &'tcx LocalDefIdSet { arena_cache desc { "reachability" } } diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs index d743c306849..4beb99e8add 100644 --- a/compiler/rustc_middle/src/ty/query.rs +++ b/compiler/rustc_middle/src/ty/query.rs @@ -50,7 +50,7 @@ use rustc_data_structures::unord::UnordSet; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir::def::{DefKind, DocLinkResMap}; -use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId}; +use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId, LocalDefIdSet}; use rustc_hir::hir_id::OwnerId; use rustc_hir::lang_items::{LangItem, LanguageItems}; use rustc_hir::{Crate, ItemLocalId, TraitCandidate}; diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index 051100c56f8..35a4550cee3 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -5,7 +5,7 @@ // makes all other generics or inline functions that it references // reachable as well. -use rustc_data_structures::fx::FxHashSet; +use hir::def_id::LocalDefIdSet; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -63,7 +63,7 @@ struct ReachableContext<'tcx> { tcx: TyCtxt<'tcx>, maybe_typeck_results: Option<&'tcx ty::TypeckResults<'tcx>>, // The set of items which must be exported in the linkage sense. - reachable_symbols: FxHashSet, + reachable_symbols: LocalDefIdSet, // A worklist of item IDs. Each item ID in this worklist will be inlined // and will be scanned for further references. // FIXME(eddyb) benchmark if this would be faster as a `VecDeque`. @@ -175,7 +175,7 @@ impl<'tcx> ReachableContext<'tcx> { // Step 2: Mark all symbols that the symbols on the worklist touch. fn propagate(&mut self) { - let mut scanned = FxHashSet::default(); + let mut scanned = LocalDefIdSet::default(); while let Some(search_item) = self.worklist.pop() { if !scanned.insert(search_item) { continue; @@ -361,7 +361,7 @@ fn has_custom_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) } -fn reachable_set(tcx: TyCtxt<'_>, (): ()) -> FxHashSet { +fn reachable_set(tcx: TyCtxt<'_>, (): ()) -> LocalDefIdSet { let effective_visibilities = &tcx.effective_visibilities(()); let any_library = diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index c0267956aab..a2caeb97297 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -109,11 +109,14 @@ impl rustc_driver::Callbacks for MiriBeRustCompilerCalls { // an empty result if `tcx.sess.opts.output_types.should_codegen()` is false. local_providers.exported_symbols = |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); + let reachable_set = tcx.with_stable_hashing_context(|hcx| { + tcx.reachable_set(()).to_sorted(&hcx, true) + }); tcx.arena.alloc_from_iter( // This is based on: // https://github.com/rust-lang/rust/blob/2962e7c0089d5c136f4e9600b7abccfbbde4973d/compiler/rustc_codegen_ssa/src/back/symbol_export.rs#L62-L63 // https://github.com/rust-lang/rust/blob/2962e7c0089d5c136f4e9600b7abccfbbde4973d/compiler/rustc_codegen_ssa/src/back/symbol_export.rs#L174 - tcx.reachable_set(()).iter().filter_map(|&local_def_id| { + reachable_set.into_iter().filter_map(|&local_def_id| { // Do the same filtering that rustc does: // https://github.com/rust-lang/rust/blob/2962e7c0089d5c136f4e9600b7abccfbbde4973d/compiler/rustc_codegen_ssa/src/back/symbol_export.rs#L84-L102 // Otherwise it may cause unexpected behaviours and ICEs From b0202d9c2c03e62cf72554af4a537969b463d3e8 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 21 Feb 2023 12:19:54 +0100 Subject: [PATCH 3/7] Use LocalDefIdSet/Map instead of FxHashSet/Map for live_symbols_and_ignored_derived_traits query. --- compiler/rustc_middle/src/query/mod.rs | 4 ++-- compiler/rustc_middle/src/ty/query.rs | 4 +++- compiler/rustc_passes/src/dead.rs | 26 ++++++++++++-------------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 743f4d9ca2a..60f090578f5 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -899,8 +899,8 @@ rustc_queries! { /// The second return value maps from ADTs to ignored derived traits (e.g. Debug and Clone) and /// their respective impl (i.e., part of the derive macro) query live_symbols_and_ignored_derived_traits(_: ()) -> &'tcx ( - FxHashSet, - FxHashMap> + LocalDefIdSet, + LocalDefIdMap> ) { arena_cache desc { "finding live symbols in crate" } diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs index 4beb99e8add..10c37b74483 100644 --- a/compiler/rustc_middle/src/ty/query.rs +++ b/compiler/rustc_middle/src/ty/query.rs @@ -50,7 +50,9 @@ use rustc_data_structures::unord::UnordSet; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir::def::{DefKind, DocLinkResMap}; -use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId, LocalDefIdSet}; +use rustc_hir::def_id::{ + CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId, LocalDefIdMap, LocalDefIdSet, +}; use rustc_hir::hir_id::OwnerId; use rustc_hir::lang_items::{LangItem, LanguageItems}; use rustc_hir::{Crate, ItemLocalId, TraitCandidate}; diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index e2f858a34b6..8a9c4cc8f7f 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -2,8 +2,8 @@ // closely. The idea is that all reachable symbols are live, codes called // from live codes are live, and everything else is dead. +use hir::def_id::{LocalDefIdMap, LocalDefIdSet}; use itertools::Itertools; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::MultiSpan; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; @@ -45,17 +45,17 @@ struct MarkSymbolVisitor<'tcx> { worklist: Vec, tcx: TyCtxt<'tcx>, maybe_typeck_results: Option<&'tcx ty::TypeckResults<'tcx>>, - live_symbols: FxHashSet, + live_symbols: LocalDefIdSet, repr_has_repr_c: bool, repr_has_repr_simd: bool, in_pat: bool, ignore_variant_stack: Vec, // maps from tuple struct constructors to tuple struct items - struct_constructors: FxHashMap, + struct_constructors: LocalDefIdMap, // maps from ADTs to ignored derived traits (e.g. Debug and Clone) // and the span of their respective impl (i.e., part of the derive // macro) - ignored_derived_traits: FxHashMap>, + ignored_derived_traits: LocalDefIdMap>, } impl<'tcx> MarkSymbolVisitor<'tcx> { @@ -237,7 +237,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { } fn mark_live_symbols(&mut self) { - let mut scanned = FxHashSet::default(); + let mut scanned = LocalDefIdSet::default(); while let Some(id) = self.worklist.pop() { if !scanned.insert(id) { continue; @@ -371,7 +371,7 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> { } if tcx.visibility(def_id).is_public() { Some(def_id) } else { None } }); - self.live_symbols.extend(live_fields); + Extend::extend(&mut self.live_symbols, live_fields); intravisit::walk_struct_def(self, def); } @@ -506,7 +506,7 @@ fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool fn check_item<'tcx>( tcx: TyCtxt<'tcx>, worklist: &mut Vec, - struct_constructors: &mut FxHashMap, + struct_constructors: &mut LocalDefIdMap, id: hir::ItemId, ) { let allow_dead_code = has_allow_dead_code_or_lang_attr(tcx, id.owner_id.def_id); @@ -583,9 +583,7 @@ fn check_foreign_item(tcx: TyCtxt<'_>, worklist: &mut Vec, id: hir:: } } -fn create_and_seed_worklist( - tcx: TyCtxt<'_>, -) -> (Vec, FxHashMap) { +fn create_and_seed_worklist(tcx: TyCtxt<'_>) -> (Vec, LocalDefIdMap) { let effective_visibilities = &tcx.effective_visibilities(()); // see `MarkSymbolVisitor::struct_constructors` let mut struct_constructors = Default::default(); @@ -617,7 +615,7 @@ fn create_and_seed_worklist( fn live_symbols_and_ignored_derived_traits( tcx: TyCtxt<'_>, (): (), -) -> (FxHashSet, FxHashMap>) { +) -> (LocalDefIdSet, LocalDefIdMap>) { let (worklist, struct_constructors) = create_and_seed_worklist(tcx); let mut symbol_visitor = MarkSymbolVisitor { worklist, @@ -629,7 +627,7 @@ fn live_symbols_and_ignored_derived_traits( in_pat: false, ignore_variant_stack: vec![], struct_constructors, - ignored_derived_traits: FxHashMap::default(), + ignored_derived_traits: Default::default(), }; symbol_visitor.mark_live_symbols(); (symbol_visitor.live_symbols, symbol_visitor.ignored_derived_traits) @@ -643,8 +641,8 @@ struct DeadVariant { struct DeadVisitor<'tcx> { tcx: TyCtxt<'tcx>, - live_symbols: &'tcx FxHashSet, - ignored_derived_traits: &'tcx FxHashMap>, + live_symbols: &'tcx LocalDefIdSet, + ignored_derived_traits: &'tcx LocalDefIdMap>, } enum ShouldWarnAboutField { From ee8bc5b0b21ab1aac0e9db76f94aadca1076f969 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 21 Feb 2023 15:15:16 +0100 Subject: [PATCH 4/7] Use FxIndexSet instead of FxHashSet for asm_target_features query. --- .../rustc_codegen_ssa/src/target_features.rs | 4 ++-- .../src/check/intrinsicck.rs | 6 +++--- compiler/rustc_middle/src/arena.rs | 3 ++- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_session/src/session.rs | 10 ++++----- compiler/rustc_target/src/asm/aarch64.rs | 4 ++-- compiler/rustc_target/src/asm/arm.rs | 12 +++++------ compiler/rustc_target/src/asm/mod.rs | 21 ++++++++++--------- compiler/rustc_target/src/asm/riscv.rs | 4 ++-- compiler/rustc_target/src/asm/x86.rs | 10 ++++----- 10 files changed, 39 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index e59fad99ad7..0dbdf4a05e8 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -1,7 +1,7 @@ use rustc_ast::ast; use rustc_attr::InstructionSetAttr; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::FxIndexSet; use rustc_errors::Applicability; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; @@ -418,7 +418,7 @@ pub fn from_target_feature( /// Computes the set of target features used in a function for the purposes of /// inline assembly. -fn asm_target_features(tcx: TyCtxt<'_>, did: DefId) -> &FxHashSet { +fn asm_target_features(tcx: TyCtxt<'_>, did: DefId) -> &FxIndexSet { let mut target_features = tcx.sess.unstable_target_features.clone(); if tcx.def_kind(did).has_codegen_attrs() { let attrs = tcx.codegen_fn_attrs(did); diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index b1d5a27be93..172b84bafb2 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -1,5 +1,5 @@ use rustc_ast::InlineAsmTemplatePiece; -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; use rustc_middle::ty::{self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy}; use rustc_session::lint; @@ -51,7 +51,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { template: &[InlineAsmTemplatePiece], is_input: bool, tied_input: Option<(&'tcx hir::Expr<'tcx>, Option)>, - target_features: &FxHashSet, + target_features: &FxIndexSet, ) -> Option { let ty = (self.get_operand_ty)(expr); if ty.has_non_region_infer() { @@ -201,7 +201,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { // (!). In that case we still need the earlier check to verify that the // register class is usable at all. if let Some(feature) = feature { - if !target_features.contains(&feature) { + if !target_features.contains(feature) { let msg = &format!("`{}` target feature is not enabled", feature); let mut err = self.tcx.sess.struct_span_err(expr.span, msg); err.note(&format!( diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index 62e44b6298b..55ea78c0474 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -94,7 +94,8 @@ macro_rules! arena_types { [] object_safety_violations: rustc_middle::traits::ObjectSafetyViolation, [] codegen_unit: rustc_middle::mir::mono::CodegenUnit<'tcx>, [decode] attribute: rustc_ast::Attribute, - [] name_set: rustc_data_structures::fx::FxHashSet, + [] name_set: rustc_data_structures::unord::UnordSet, + [] ordered_name_set: rustc_data_structures::fx::FxIndexSet, [] hir_id_set: rustc_hir::HirIdSet, // Interned types diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 60f090578f5..be5aa49a0d0 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1212,7 +1212,7 @@ rustc_queries! { separate_provide_extern } - query asm_target_features(def_id: DefId) -> &'tcx FxHashSet { + query asm_target_features(def_id: DefId) -> &'tcx FxIndexSet { desc { |tcx| "computing target features for inline asm of `{}`", tcx.def_path_str(def_id) } } diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 446ba63ed1c..0ef3b026ab0 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -11,7 +11,7 @@ use crate::{filesearch, lint}; pub use rustc_ast::attr::MarkedAttrs; pub use rustc_ast::Attribute; use rustc_data_structures::flock; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_data_structures::jobserver::{self, Client}; use rustc_data_structures::profiling::{duration_to_secs_str, SelfProfiler, SelfProfilerRef}; use rustc_data_structures::sync::{ @@ -207,10 +207,10 @@ pub struct Session { pub asm_arch: Option, /// Set of enabled features for the current target. - pub target_features: FxHashSet, + pub target_features: FxIndexSet, /// Set of enabled features for the current target, including unstable ones. - pub unstable_target_features: FxHashSet, + pub unstable_target_features: FxIndexSet, } pub struct PerfStats { @@ -1484,8 +1484,8 @@ pub fn build_session( ctfe_backtrace, miri_unleashed_features: Lock::new(Default::default()), asm_arch, - target_features: FxHashSet::default(), - unstable_target_features: FxHashSet::default(), + target_features: Default::default(), + unstable_target_features: Default::default(), }; validate_commandline_args_with_session_available(&sess); diff --git a/compiler/rustc_target/src/asm/aarch64.rs b/compiler/rustc_target/src/asm/aarch64.rs index 28493c7700f..97132311a5c 100644 --- a/compiler/rustc_target/src/asm/aarch64.rs +++ b/compiler/rustc_target/src/asm/aarch64.rs @@ -1,6 +1,6 @@ use super::{InlineAsmArch, InlineAsmType}; use crate::spec::{RelocModel, Target}; -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::FxIndexSet; use rustc_macros::HashStable_Generic; use rustc_span::Symbol; use std::fmt; @@ -80,7 +80,7 @@ pub fn target_reserves_x18(target: &Target) -> bool { fn reserved_x18( _arch: InlineAsmArch, _reloc_model: RelocModel, - _target_features: &FxHashSet, + _target_features: &FxIndexSet, target: &Target, _is_clobber: bool, ) -> Result<(), &'static str> { diff --git a/compiler/rustc_target/src/asm/arm.rs b/compiler/rustc_target/src/asm/arm.rs index ec7429a3065..514e30ae020 100644 --- a/compiler/rustc_target/src/asm/arm.rs +++ b/compiler/rustc_target/src/asm/arm.rs @@ -1,6 +1,6 @@ use super::{InlineAsmArch, InlineAsmType}; use crate::spec::{RelocModel, Target}; -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::FxIndexSet; use rustc_macros::HashStable_Generic; use rustc_span::{sym, Symbol}; use std::fmt; @@ -64,14 +64,14 @@ impl ArmInlineAsmRegClass { } // This uses the same logic as useR7AsFramePointer in LLVM -fn frame_pointer_is_r7(target_features: &FxHashSet, target: &Target) -> bool { +fn frame_pointer_is_r7(target_features: &FxIndexSet, target: &Target) -> bool { target.is_like_osx || (!target.is_like_windows && target_features.contains(&sym::thumb_mode)) } fn frame_pointer_r11( arch: InlineAsmArch, reloc_model: RelocModel, - target_features: &FxHashSet, + target_features: &FxIndexSet, target: &Target, is_clobber: bool, ) -> Result<(), &'static str> { @@ -87,7 +87,7 @@ fn frame_pointer_r11( fn frame_pointer_r7( _arch: InlineAsmArch, _reloc_model: RelocModel, - target_features: &FxHashSet, + target_features: &FxIndexSet, target: &Target, _is_clobber: bool, ) -> Result<(), &'static str> { @@ -101,7 +101,7 @@ fn frame_pointer_r7( fn not_thumb1( _arch: InlineAsmArch, _reloc_model: RelocModel, - target_features: &FxHashSet, + target_features: &FxIndexSet, _target: &Target, is_clobber: bool, ) -> Result<(), &'static str> { @@ -118,7 +118,7 @@ fn not_thumb1( fn reserved_r9( arch: InlineAsmArch, reloc_model: RelocModel, - target_features: &FxHashSet, + target_features: &FxIndexSet, target: &Target, is_clobber: bool, ) -> Result<(), &'static str> { diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index 70cd883be09..0dbfd426781 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -1,6 +1,6 @@ use crate::spec::Target; use crate::{abi::Size, spec::RelocModel}; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_macros::HashStable_Generic; use rustc_span::Symbol; use std::fmt; @@ -37,13 +37,14 @@ macro_rules! def_reg_class { pub(super) fn regclass_map() -> rustc_data_structures::fx::FxHashMap< super::InlineAsmRegClass, - rustc_data_structures::fx::FxHashSet, + rustc_data_structures::fx::FxIndexSet, > { - use rustc_data_structures::fx::{FxHashMap, FxHashSet}; + use rustc_data_structures::fx::FxHashMap; + use rustc_data_structures::fx::FxIndexSet; use super::InlineAsmRegClass; let mut map = FxHashMap::default(); $( - map.insert(InlineAsmRegClass::$arch($arch_regclass::$class), FxHashSet::default()); + map.insert(InlineAsmRegClass::$arch($arch_regclass::$class), FxIndexSet::default()); )* map } @@ -94,7 +95,7 @@ macro_rules! def_regs { pub fn validate(self, _arch: super::InlineAsmArch, _reloc_model: crate::spec::RelocModel, - _target_features: &rustc_data_structures::fx::FxHashSet, + _target_features: &rustc_data_structures::fx::FxIndexSet, _target: &crate::spec::Target, _is_clobber: bool, ) -> Result<(), &'static str> { @@ -118,11 +119,11 @@ macro_rules! def_regs { pub(super) fn fill_reg_map( _arch: super::InlineAsmArch, _reloc_model: crate::spec::RelocModel, - _target_features: &rustc_data_structures::fx::FxHashSet, + _target_features: &rustc_data_structures::fx::FxIndexSet, _target: &crate::spec::Target, _map: &mut rustc_data_structures::fx::FxHashMap< super::InlineAsmRegClass, - rustc_data_structures::fx::FxHashSet, + rustc_data_structures::fx::FxIndexSet, >, ) { #[allow(unused_imports)] @@ -334,7 +335,7 @@ impl InlineAsmReg { self, arch: InlineAsmArch, reloc_model: RelocModel, - target_features: &FxHashSet, + target_features: &FxIndexSet, target: &Target, is_clobber: bool, ) -> Result<(), &'static str> { @@ -701,9 +702,9 @@ impl fmt::Display for InlineAsmType { pub fn allocatable_registers( arch: InlineAsmArch, reloc_model: RelocModel, - target_features: &FxHashSet, + target_features: &FxIndexSet, target: &crate::spec::Target, -) -> FxHashMap> { +) -> FxHashMap> { match arch { InlineAsmArch::X86 | InlineAsmArch::X86_64 => { let mut map = x86::regclass_map(); diff --git a/compiler/rustc_target/src/asm/riscv.rs b/compiler/rustc_target/src/asm/riscv.rs index e41bdc9a58c..dea6d50fe2b 100644 --- a/compiler/rustc_target/src/asm/riscv.rs +++ b/compiler/rustc_target/src/asm/riscv.rs @@ -1,6 +1,6 @@ use super::{InlineAsmArch, InlineAsmType}; use crate::spec::{RelocModel, Target}; -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::FxIndexSet; use rustc_macros::HashStable_Generic; use rustc_span::{sym, Symbol}; use std::fmt; @@ -55,7 +55,7 @@ impl RiscVInlineAsmRegClass { fn not_e( _arch: InlineAsmArch, _reloc_model: RelocModel, - target_features: &FxHashSet, + target_features: &FxIndexSet, _target: &Target, _is_clobber: bool, ) -> Result<(), &'static str> { diff --git a/compiler/rustc_target/src/asm/x86.rs b/compiler/rustc_target/src/asm/x86.rs index 5eae07f141f..3902dac7ff6 100644 --- a/compiler/rustc_target/src/asm/x86.rs +++ b/compiler/rustc_target/src/asm/x86.rs @@ -1,6 +1,6 @@ use super::{InlineAsmArch, InlineAsmType}; use crate::spec::{RelocModel, Target}; -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::FxIndexSet; use rustc_macros::HashStable_Generic; use rustc_span::Symbol; use std::fmt; @@ -147,7 +147,7 @@ impl X86InlineAsmRegClass { fn x86_64_only( arch: InlineAsmArch, _reloc_model: RelocModel, - _target_features: &FxHashSet, + _target_features: &FxIndexSet, _target: &Target, _is_clobber: bool, ) -> Result<(), &'static str> { @@ -161,7 +161,7 @@ fn x86_64_only( fn high_byte( arch: InlineAsmArch, _reloc_model: RelocModel, - _target_features: &FxHashSet, + _target_features: &FxIndexSet, _target: &Target, _is_clobber: bool, ) -> Result<(), &'static str> { @@ -174,7 +174,7 @@ fn high_byte( fn rbx_reserved( arch: InlineAsmArch, _reloc_model: RelocModel, - _target_features: &FxHashSet, + _target_features: &FxIndexSet, _target: &Target, _is_clobber: bool, ) -> Result<(), &'static str> { @@ -190,7 +190,7 @@ fn rbx_reserved( fn esi_reserved( arch: InlineAsmArch, _reloc_model: RelocModel, - _target_features: &FxHashSet, + _target_features: &FxIndexSet, _target: &Target, _is_clobber: bool, ) -> Result<(), &'static str> { From 422208ae52564c3b8cbf8416ffd1c92e9c80a3c0 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 21 Feb 2023 15:18:10 +0100 Subject: [PATCH 5/7] Use UnordSet instead of FxHashSet for names_imported_by_glob_use query. --- compiler/rustc_data_structures/src/unord.rs | 33 ++++++++++++++++++- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 5 ++- compiler/rustc_middle/src/ty/query.rs | 2 +- compiler/rustc_passes/src/dead.rs | 2 +- .../clippy_lints/src/wildcard_imports.rs | 10 ++---- 6 files changed, 42 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_data_structures/src/unord.rs b/compiler/rustc_data_structures/src/unord.rs index f35f18e51cb..5c2435a0122 100644 --- a/compiler/rustc_data_structures/src/unord.rs +++ b/compiler/rustc_data_structures/src/unord.rs @@ -109,6 +109,12 @@ impl> UnordItems { } } +impl UnordItems> { + pub fn empty() -> Self { + UnordItems(std::iter::empty()) + } +} + impl<'a, T: Clone + 'a, I: Iterator> UnordItems<&'a T, I> { #[inline] pub fn cloned(self) -> UnordItems> { @@ -133,6 +139,20 @@ impl> UnordItems { items } + #[inline] + pub fn into_sorted_stable_ord(self, use_stable_sort: bool) -> Vec + where + T: Ord + StableOrd, + { + let mut items: Vec = self.0.collect(); + if use_stable_sort { + items.sort(); + } else { + items.sort_unstable() + } + items + } + pub fn into_sorted_small_vec(self, hcx: &HCX) -> SmallVec<[T; LEN]> where T: ToStableHashKey, @@ -175,6 +195,11 @@ impl UnordSet { self.inner.len() } + #[inline] + pub fn is_empty(&self) -> bool { + self.inner.is_empty() + } + #[inline] pub fn insert(&mut self, v: V) -> bool { self.inner.insert(v) @@ -253,7 +278,7 @@ impl UnordSet { // We can safely extend this UnordSet from a set of unordered values because that // won't expose the internal ordering anywhere. #[inline] - pub fn extend>(&mut self, items: UnordItems) { + pub fn extend_unord>(&mut self, items: UnordItems) { self.inner.extend(items.0) } @@ -277,6 +302,12 @@ impl FromIterator for UnordSet { } } +impl From> for UnordSet { + fn from(value: FxHashSet) -> Self { + UnordSet { inner: value } + } +} + impl> HashStable for UnordSet { #[inline] fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index be5aa49a0d0..9f25d0b2e43 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1826,7 +1826,7 @@ rustc_queries! { query maybe_unused_trait_imports(_: ()) -> &'tcx FxIndexSet { desc { "fetching potentially unused trait imports" } } - query names_imported_by_glob_use(def_id: LocalDefId) -> &'tcx FxHashSet { + query names_imported_by_glob_use(def_id: LocalDefId) -> &'tcx UnordSet { desc { |tcx| "finding names imported by glob use for `{}`", tcx.def_path_str(def_id.to_def_id()) } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 0333198c203..4c3525d8a11 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -37,6 +37,7 @@ use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::steal::Steal; use rustc_data_structures::sync::{self, Lock, Lrc, MappedReadGuard, ReadGuard, WorkerLocal}; +use rustc_data_structures::unord::UnordSet; use rustc_errors::{ DecorateLint, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, MultiSpan, }; @@ -2488,7 +2489,9 @@ pub fn provide(providers: &mut ty::query::Providers) { providers.maybe_unused_trait_imports = |tcx, ()| &tcx.resolutions(()).maybe_unused_trait_imports; providers.names_imported_by_glob_use = |tcx, id| { - tcx.arena.alloc(tcx.resolutions(()).glob_map.get(&id).cloned().unwrap_or_default()) + tcx.arena.alloc(UnordSet::from( + tcx.resolutions(()).glob_map.get(&id).cloned().unwrap_or_default(), + )) }; providers.extern_mod_stmt_cnum = diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs index 10c37b74483..3c185912776 100644 --- a/compiler/rustc_middle/src/ty/query.rs +++ b/compiler/rustc_middle/src/ty/query.rs @@ -41,7 +41,7 @@ use rustc_arena::TypedArena; use rustc_ast as ast; use rustc_ast::expand::allocator::AllocatorKind; use rustc_attr as attr; -use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; +use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet}; use rustc_data_structures::steal::Steal; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::Lrc; diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 8a9c4cc8f7f..75273d1fb7d 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -371,7 +371,7 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> { } if tcx.visibility(def_id).is_public() { Some(def_id) } else { None } }); - Extend::extend(&mut self.live_symbols, live_fields); + self.live_symbols.extend(live_fields); intravisit::walk_struct_def(self, def); } diff --git a/src/tools/clippy/clippy_lints/src/wildcard_imports.rs b/src/tools/clippy/clippy_lints/src/wildcard_imports.rs index e4d1ee195c4..e105452e1c5 100644 --- a/src/tools/clippy/clippy_lints/src/wildcard_imports.rs +++ b/src/tools/clippy/clippy_lints/src/wildcard_imports.rs @@ -155,14 +155,10 @@ impl LateLintPass<'_> for WildcardImports { ) }; - let imports_string = if used_imports.len() == 1 { - used_imports.iter().next().unwrap().to_string() + let mut imports = used_imports.items().map(ToString::to_string).into_sorted_stable_ord(false); + let imports_string = if imports.len() == 1 { + imports.pop().unwrap() } else { - let mut imports = used_imports - .iter() - .map(ToString::to_string) - .collect::>(); - imports.sort(); if braced_glob { imports.join(", ") } else { From 04e5fa3ce2a6a2b74c2940364b13bc106d8cadb6 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 21 Feb 2023 15:21:57 +0100 Subject: [PATCH 6/7] Remove last instances of HashSet in query result types. --- .../rustc_hir_analysis/src/check_unused.rs | 2 +- compiler/rustc_middle/src/mir/query.rs | 4 ++-- .../rustc_mir_transform/src/check_unsafety.rs | 22 +++++++++---------- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check_unused.rs b/compiler/rustc_hir_analysis/src/check_unused.rs index f3f5851d8f9..268b9ac530f 100644 --- a/compiler/rustc_hir_analysis/src/check_unused.rs +++ b/compiler/rustc_hir_analysis/src/check_unused.rs @@ -10,7 +10,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) { for item_def_id in tcx.hir().body_owners() { let imports = tcx.used_trait_imports(item_def_id); debug!("GatherVisitor: item_def_id={:?} with imports {:#?}", item_def_id, imports); - used_trait_imports.extend(imports.items().copied()); + used_trait_imports.extend_unord(imports.items().copied()); } for &id in tcx.maybe_unused_trait_imports(()) { diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index e2ab3fd35b3..09b356bb5b5 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -2,7 +2,7 @@ use crate::mir::{Body, ConstantKind, Promoted}; use crate::ty::{self, OpaqueHiddenType, Ty, TyCtxt}; -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::unord::UnordSet; use rustc_data_structures::vec_map::VecMap; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; @@ -123,7 +123,7 @@ pub struct UnsafetyCheckResult { pub violations: Vec, /// Used `unsafe` blocks in this function. This is used for the "unused_unsafe" lint. - pub used_unsafe_blocks: FxHashSet, + pub used_unsafe_blocks: UnordSet, /// This is `Some` iff the item is not a closure. pub unused_unsafes: Option>, diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs index d00ee1f4bab..71605113dd5 100644 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ b/compiler/rustc_mir_transform/src/check_unsafety.rs @@ -1,4 +1,4 @@ -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::unord::{UnordItems, UnordSet}; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::DefKind; @@ -24,7 +24,7 @@ pub struct UnsafetyChecker<'a, 'tcx> { param_env: ty::ParamEnv<'tcx>, /// Used `unsafe` blocks in this function. This is used for the "unused_unsafe" lint. - used_unsafe_blocks: FxHashSet, + used_unsafe_blocks: UnordSet, } impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { @@ -129,7 +129,7 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> { let def_id = def_id.expect_local(); let UnsafetyCheckResult { violations, used_unsafe_blocks, .. } = self.tcx.unsafety_check_result(def_id); - self.register_violations(violations, used_unsafe_blocks.iter().copied()); + self.register_violations(violations, used_unsafe_blocks.items().copied()); } }, _ => {} @@ -151,7 +151,7 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> { let local_def_id = def_id.expect_local(); let UnsafetyCheckResult { violations, used_unsafe_blocks, .. } = self.tcx.unsafety_check_result(local_def_id); - self.register_violations(violations, used_unsafe_blocks.iter().copied()); + self.register_violations(violations, used_unsafe_blocks.items().copied()); } } } @@ -268,14 +268,14 @@ impl<'tcx> UnsafetyChecker<'_, 'tcx> { .lint_root; self.register_violations( [&UnsafetyViolation { source_info, lint_root, kind, details }], - [], + UnordItems::empty(), ); } fn register_violations<'a>( &mut self, violations: impl IntoIterator, - new_used_unsafe_blocks: impl IntoIterator, + new_used_unsafe_blocks: UnordItems>, ) { let safety = self.body.source_scopes[self.source_info.scope] .local_data @@ -308,9 +308,7 @@ impl<'tcx> UnsafetyChecker<'_, 'tcx> { }), }; - new_used_unsafe_blocks.into_iter().for_each(|hir_id| { - self.used_unsafe_blocks.insert(hir_id); - }); + self.used_unsafe_blocks.extend_unord(new_used_unsafe_blocks); } fn check_mut_borrowing_layout_constrained_field( &mut self, @@ -407,7 +405,7 @@ enum Context { struct UnusedUnsafeVisitor<'a, 'tcx> { tcx: TyCtxt<'tcx>, - used_unsafe_blocks: &'a FxHashSet, + used_unsafe_blocks: &'a UnordSet, context: Context, unused_unsafes: &'a mut Vec<(HirId, UnusedUnsafe)>, } @@ -458,7 +456,7 @@ impl<'tcx> intravisit::Visitor<'tcx> for UnusedUnsafeVisitor<'_, 'tcx> { fn check_unused_unsafe( tcx: TyCtxt<'_>, def_id: LocalDefId, - used_unsafe_blocks: &FxHashSet, + used_unsafe_blocks: &UnordSet, ) -> Vec<(HirId, UnusedUnsafe)> { let body_id = tcx.hir().maybe_body_owned_by(def_id); @@ -505,7 +503,7 @@ fn unsafety_check_result( if body.is_custom_mir() { return tcx.arena.alloc(UnsafetyCheckResult { violations: Vec::new(), - used_unsafe_blocks: FxHashSet::default(), + used_unsafe_blocks: Default::default(), unused_unsafes: Some(Vec::new()), }); } From b79f0261f87ff38de6fee6a6f6ce9915a8f0e6b4 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 21 Feb 2023 15:29:12 +0100 Subject: [PATCH 7/7] Do not implement HashStable for HashSet. --- .../rustc_data_structures/src/stable_hasher.rs | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs index e0d77cdaebb..de9842156d6 100644 --- a/compiler/rustc_data_structures/src/stable_hasher.rs +++ b/compiler/rustc_data_structures/src/stable_hasher.rs @@ -617,18 +617,10 @@ where } } -impl HashStable for ::std::collections::HashSet -where - K: ToStableHashKey + Eq, - R: BuildHasher, -{ - fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { - stable_hash_reduce(hcx, hasher, self.iter(), self.len(), |hasher, hcx, key| { - let key = key.to_stable_hash_key(hcx); - key.hash_stable(hcx, hasher); - }); - } -} +// It is not safe to implement HashStable for HashSet or any other collection type +// with unstable but observable iteration order. +// See https://github.com/rust-lang/compiler-team/issues/533 for further information. +impl !HashStable for std::collections::HashSet {} impl HashStable for ::std::collections::BTreeMap where