From 2e7dbb42c7f343daa22f4b4e21db4c77e834a458 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 26 Dec 2019 20:03:45 +0100 Subject: [PATCH 1/7] Move reachable.rs to librustc_passes. --- src/{librustc/middle => librustc_passes}/reachable.rs | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{librustc/middle => librustc_passes}/reachable.rs (100%) diff --git a/src/librustc/middle/reachable.rs b/src/librustc_passes/reachable.rs similarity index 100% rename from src/librustc/middle/reachable.rs rename to src/librustc_passes/reachable.rs From 4922310a3bcc36adc21e7db11acb038918b9a2a7 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 26 Dec 2019 23:24:36 +0100 Subject: [PATCH 2/7] Move reachable_set query in librustc_passes. --- src/librustc/lib.rs | 1 - src/librustc/query/mod.rs | 2 +- src/librustc/ty/query/mod.rs | 3 +- .../back/symbol_export.rs | 3 +- src/librustc_interface/passes.rs | 4 +- src/librustc_passes/lib.rs | 2 + src/librustc_passes/reachable.rs | 38 ++++++++----------- 7 files changed, 22 insertions(+), 31 deletions(-) diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 55713aedbcb67..22bd333b6dded 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -105,7 +105,6 @@ pub mod middle { pub mod lang_items; pub mod lib_features; pub mod privacy; - pub mod reachable; pub mod recursion_limit; pub mod region; pub mod resolve_lifetime; diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index 24841a1ccf456..9b7ae0993357b 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -510,7 +510,7 @@ rustc_queries! { } Other { - query reachable_set(_: CrateNum) -> ReachableSet { + query reachable_set(_: CrateNum) -> Lrc { desc { "reachability" } } diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 8be0536a18ec6..f523cee49ec63 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -10,7 +10,6 @@ use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel}; use crate::middle::lang_items::{LangItem, LanguageItems}; use crate::middle::lib_features::LibFeatures; use crate::middle::privacy::AccessLevels; -use crate::middle::reachable::ReachableSet; use crate::middle::region; use crate::middle::resolve_lifetime::{ObjectLifetimeDefault, Region, ResolveLifetimes}; use crate::middle::stability::{self, DeprecationEntry}; @@ -37,7 +36,7 @@ use crate::ty::subst::SubstsRef; use crate::ty::util::NeedsDrop; use crate::ty::{self, AdtSizedConstraint, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt}; use crate::util::common::ErrorReported; -use crate::util::nodemap::{DefIdMap, DefIdSet}; +use crate::util::nodemap::{DefIdMap, DefIdSet, HirIdSet}; use rustc_data_structures::profiling::ProfileCategory::*; use rustc_data_structures::fingerprint::Fingerprint; diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index 07ff5c362ebbf..5bdb310f9b546 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -65,7 +65,6 @@ fn reachable_non_generics_provider( let mut reachable_non_generics: DefIdMap<_> = tcx .reachable_set(LOCAL_CRATE) - .0 .iter() .filter_map(|&hir_id| { // We want to ignore some FFI functions that are not exposed from @@ -313,7 +312,7 @@ fn upstream_monomorphizations_for_provider( fn is_unreachable_local_definition_provider(tcx: TyCtxt<'_>, def_id: DefId) -> bool { if let Some(hir_id) = tcx.hir().as_local_hir_id(def_id) { - !tcx.reachable_set(LOCAL_CRATE).0.contains(&hir_id) + !tcx.reachable_set(LOCAL_CRATE).contains(&hir_id) } else { bug!("is_unreachable_local_definition called with non-local DefId: {:?}", def_id) } diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 9d0ec585c203b..b4522f4c66531 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -10,7 +10,7 @@ use rustc::hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc::hir::lowering::lower_crate; use rustc::lint; use rustc::middle::cstore::{CrateStore, MetadataLoader, MetadataLoaderDyn}; -use rustc::middle::{self, reachable, resolve_lifetime, stability}; +use rustc::middle::{self, resolve_lifetime, stability}; use rustc::session::config::{self, CrateType, Input, OutputFilenames, OutputType}; use rustc::session::config::{PpMode, PpSourceMode}; use rustc::session::search_paths::PathKind; @@ -678,14 +678,12 @@ pub fn default_provide(providers: &mut ty::query::Providers<'_>) { plugin::build::provide(providers); hir::provide(providers); mir::provide(providers); - reachable::provide(providers); resolve_lifetime::provide(providers); rustc_privacy::provide(providers); typeck::provide(providers); ty::provide(providers); traits::provide(providers); stability::provide(providers); - reachable::provide(providers); rustc_passes::provide(providers); rustc_traits::provide(providers); middle::region::provide(providers); diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs index 5c2ccd28383b3..fd34b6e6f47b8 100644 --- a/src/librustc_passes/lib.rs +++ b/src/librustc_passes/lib.rs @@ -28,6 +28,7 @@ mod intrinsicck; pub mod layout_test; mod liveness; pub mod loops; +mod reachable; pub fn provide(providers: &mut Providers<'_>) { check_const::provide(providers); @@ -35,4 +36,5 @@ pub fn provide(providers: &mut Providers<'_>) { loops::provide(providers); liveness::provide(providers); intrinsicck::provide(providers); + reachable::provide(providers); } diff --git a/src/librustc_passes/reachable.rs b/src/librustc_passes/reachable.rs index c6598f2d328bf..5241d9ea43f13 100644 --- a/src/librustc_passes/reachable.rs +++ b/src/librustc_passes/reachable.rs @@ -5,23 +5,22 @@ // makes all other generics or inline functions that it references // reachable as well. -use crate::hir::def::{DefKind, Res}; -use crate::hir::def_id::{CrateNum, DefId}; -use crate::hir::Node; -use crate::hir::{CodegenFnAttrFlags, CodegenFnAttrs}; -use crate::middle::privacy; -use crate::session::config; -use crate::ty::query::Providers; -use crate::ty::{self, TyCtxt}; -use crate::util::nodemap::{FxHashSet, HirIdSet}; +use rustc::hir::def::{DefKind, Res}; +use rustc::hir::def_id::{CrateNum, DefId}; +use rustc::hir::Node; +use rustc::hir::{CodegenFnAttrFlags, CodegenFnAttrs}; +use rustc::middle::privacy; +use rustc::session::config; +use rustc::ty::query::Providers; +use rustc::ty::{self, TyCtxt}; +use rustc::util::nodemap::{FxHashSet, HirIdSet}; use rustc_data_structures::sync::Lrc; -use crate::hir; -use crate::hir::def_id::LOCAL_CRATE; -use crate::hir::intravisit; -use crate::hir::intravisit::{NestedVisitorMap, Visitor}; -use crate::hir::itemlikevisit::ItemLikeVisitor; -use rustc_macros::HashStable; +use rustc::hir; +use rustc::hir::def_id::LOCAL_CRATE; +use rustc::hir::intravisit; +use rustc::hir::intravisit::{NestedVisitorMap, Visitor}; +use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc_target::spec::abi::Abi; // Returns true if the given item must be inlined because it may be @@ -378,12 +377,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx } } -// We introduce a new-type here, so we can have a specialized HashStable -// implementation for it. -#[derive(Clone, HashStable)] -pub struct ReachableSet(pub Lrc); - -fn reachable_set(tcx: TyCtxt<'_>, crate_num: CrateNum) -> ReachableSet { +fn reachable_set(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Lrc { debug_assert!(crate_num == LOCAL_CRATE); let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE); @@ -429,7 +423,7 @@ fn reachable_set(tcx: TyCtxt<'_>, crate_num: CrateNum) -> ReachableSet { debug!("Inline reachability shows: {:?}", reachable_context.reachable_symbols); // Return the set of reachable symbols. - ReachableSet(Lrc::new(reachable_context.reachable_symbols)) + Lrc::new(reachable_context.reachable_symbols) } pub fn provide(providers: &mut Providers<'_>) { From 2a14d1658367ecb9e465d1b45d4f4258982dd372 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 26 Dec 2019 23:26:24 +0100 Subject: [PATCH 3/7] Move diagnostic_items.rs to librustc_passes. --- src/{librustc/middle => librustc_passes}/diagnostic_items.rs | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{librustc/middle => librustc_passes}/diagnostic_items.rs (100%) diff --git a/src/librustc/middle/diagnostic_items.rs b/src/librustc_passes/diagnostic_items.rs similarity index 100% rename from src/librustc/middle/diagnostic_items.rs rename to src/librustc_passes/diagnostic_items.rs From fd4d50d4429f16edbc61d509bd3a31e28180b851 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 26 Dec 2019 23:33:40 +0100 Subject: [PATCH 4/7] Move diagnostic_items queries to librustc_passes. --- src/librustc/lib.rs | 1 - src/librustc/ty/context.rs | 8 -------- src/librustc_passes/diagnostic_items.rs | 26 ++++++++++++++++++------- src/librustc_passes/lib.rs | 2 ++ 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 22bd333b6dded..38dcbc8e3fbb5 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -99,7 +99,6 @@ pub mod lint; pub mod middle { pub mod cstore; pub mod dependency_format; - pub mod diagnostic_items; pub mod exported_symbols; pub mod free_region; pub mod lang_items; diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 0fb294bb9da60..566c814f947f3 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -2759,14 +2759,6 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { assert_eq!(id, LOCAL_CRATE); tcx.arena.alloc(middle::lang_items::collect(tcx)) }; - providers.diagnostic_items = |tcx, id| { - assert_eq!(id, LOCAL_CRATE); - middle::diagnostic_items::collect(tcx) - }; - providers.all_diagnostic_items = |tcx, id| { - assert_eq!(id, LOCAL_CRATE); - middle::diagnostic_items::collect_all(tcx) - }; providers.maybe_unused_trait_import = |tcx, id| tcx.maybe_unused_trait_imports.contains(&id); providers.maybe_unused_extern_crates = |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); diff --git a/src/librustc_passes/diagnostic_items.rs b/src/librustc_passes/diagnostic_items.rs index 32ef1338712bb..65138fad43bd8 100644 --- a/src/librustc_passes/diagnostic_items.rs +++ b/src/librustc_passes/diagnostic_items.rs @@ -9,12 +9,13 @@ //! //! * Compiler internal types like `Ty` and `TyCtxt` -use crate::hir::def_id::{DefId, LOCAL_CRATE}; -use crate::ty::TyCtxt; -use crate::util::nodemap::FxHashMap; +use rustc::hir::def_id::{DefId, LOCAL_CRATE}; +use rustc::ty::query::Providers; +use rustc::ty::TyCtxt; +use rustc::util::nodemap::FxHashMap; -use crate::hir; -use crate::hir::itemlikevisit::ItemLikeVisitor; +use rustc::hir; +use rustc::hir::itemlikevisit::ItemLikeVisitor; use syntax::ast; use syntax::symbol::{sym, Symbol}; @@ -93,7 +94,7 @@ fn extract(attrs: &[ast::Attribute]) -> Option { } /// Traverse and collect the diagnostic items in the current -pub fn collect<'tcx>(tcx: TyCtxt<'tcx>) -> &'tcx FxHashMap { +fn collect<'tcx>(tcx: TyCtxt<'tcx>) -> &'tcx FxHashMap { // Initialize the collector. let mut collector = DiagnosticItemCollector::new(tcx); @@ -104,7 +105,7 @@ pub fn collect<'tcx>(tcx: TyCtxt<'tcx>) -> &'tcx FxHashMap { } /// Traverse and collect all the diagnostic items in all crates. -pub fn collect_all<'tcx>(tcx: TyCtxt<'tcx>) -> &'tcx FxHashMap { +fn collect_all<'tcx>(tcx: TyCtxt<'tcx>) -> &'tcx FxHashMap { // Initialize the collector. let mut collector = FxHashMap::default(); @@ -117,3 +118,14 @@ pub fn collect_all<'tcx>(tcx: TyCtxt<'tcx>) -> &'tcx FxHashMap { tcx.arena.alloc(collector) } + +pub fn provide(providers: &mut Providers<'_>) { + providers.diagnostic_items = |tcx, id| { + assert_eq!(id, LOCAL_CRATE); + collect(tcx) + }; + providers.all_diagnostic_items = |tcx, id| { + assert_eq!(id, LOCAL_CRATE); + collect_all(tcx) + }; +} diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs index fd34b6e6f47b8..1ac03122c4a3e 100644 --- a/src/librustc_passes/lib.rs +++ b/src/librustc_passes/lib.rs @@ -22,6 +22,7 @@ use rustc::ty::query::Providers; pub mod ast_validation; mod check_const; pub mod dead; +mod diagnostic_items; pub mod entry; pub mod hir_stats; mod intrinsicck; @@ -32,6 +33,7 @@ mod reachable; pub fn provide(providers: &mut Providers<'_>) { check_const::provide(providers); + diagnostic_items::provide(providers); entry::provide(providers); loops::provide(providers); liveness::provide(providers); From ec3a9f64f1e08520a486c2a1dfffca7bb7332d26 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 27 Dec 2019 18:43:22 +0100 Subject: [PATCH 5/7] Move lib_features.rs in librustc_passes. --- src/{librustc/middle => librustc_passes}/lib_features.rs | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{librustc/middle => librustc_passes}/lib_features.rs (100%) diff --git a/src/librustc/middle/lib_features.rs b/src/librustc_passes/lib_features.rs similarity index 100% rename from src/librustc/middle/lib_features.rs rename to src/librustc_passes/lib_features.rs From 57681628f9138a76302d0eb41cac69c44b00f75a Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 27 Dec 2019 18:52:36 +0100 Subject: [PATCH 6/7] Move get_lib_features query in librustc_passes. --- src/librustc/lib.rs | 25 +++++++++++++++- src/librustc/ty/context.rs | 4 --- src/librustc_passes/lib.rs | 2 ++ src/librustc_passes/lib_features.rs | 44 +++++++++++------------------ 4 files changed, 42 insertions(+), 33 deletions(-) diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 38dcbc8e3fbb5..35c20cdbaf591 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -102,7 +102,30 @@ pub mod middle { pub mod exported_symbols; pub mod free_region; pub mod lang_items; - pub mod lib_features; + pub mod lib_features { + use rustc_data_structures::fx::{FxHashMap, FxHashSet}; + use syntax::symbol::Symbol; + + #[derive(HashStable)] + pub struct LibFeatures { + // A map from feature to stabilisation version. + pub stable: FxHashMap, + pub unstable: FxHashSet, + } + + impl LibFeatures { + pub fn to_vec(&self) -> Vec<(Symbol, Option)> { + let mut all_features: Vec<_> = self + .stable + .iter() + .map(|(f, s)| (*f, Some(*s))) + .chain(self.unstable.iter().map(|f| (*f, None))) + .collect(); + all_features.sort_unstable_by_key(|f| f.0.as_str()); + all_features + } + } + } pub mod privacy; pub mod recursion_limit; pub mod region; diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 566c814f947f3..69e3358d6f65e 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -2751,10 +2751,6 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { assert_eq!(id, LOCAL_CRATE); tcx.crate_name }; - providers.get_lib_features = |tcx, id| { - assert_eq!(id, LOCAL_CRATE); - tcx.arena.alloc(middle::lib_features::collect(tcx)) - }; providers.get_lang_items = |tcx, id| { assert_eq!(id, LOCAL_CRATE); tcx.arena.alloc(middle::lang_items::collect(tcx)) diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs index 1ac03122c4a3e..da781f2bae528 100644 --- a/src/librustc_passes/lib.rs +++ b/src/librustc_passes/lib.rs @@ -27,6 +27,7 @@ pub mod entry; pub mod hir_stats; mod intrinsicck; pub mod layout_test; +mod lib_features; mod liveness; pub mod loops; mod reachable; @@ -35,6 +36,7 @@ pub fn provide(providers: &mut Providers<'_>) { check_const::provide(providers); diagnostic_items::provide(providers); entry::provide(providers); + lib_features::provide(providers); loops::provide(providers); liveness::provide(providers); intrinsicck::provide(providers); diff --git a/src/librustc_passes/lib_features.rs b/src/librustc_passes/lib_features.rs index b4ddb09861df5..0b0183f3cce04 100644 --- a/src/librustc_passes/lib_features.rs +++ b/src/librustc_passes/lib_features.rs @@ -4,38 +4,19 @@ // and `#[unstable (..)]`), but are not declared in one single location // (unlike lang features), which means we need to collect them instead. -use crate::hir::intravisit::{self, NestedVisitorMap, Visitor}; -use crate::ty::TyCtxt; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_macros::HashStable; +use rustc::hir::def_id::LOCAL_CRATE; +use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor}; +use rustc::middle::lib_features::LibFeatures; +use rustc::ty::query::Providers; +use rustc::ty::TyCtxt; use syntax::ast::{Attribute, MetaItem, MetaItemKind}; use syntax::symbol::Symbol; use syntax_pos::{sym, Span}; use rustc_error_codes::*; -#[derive(HashStable)] -pub struct LibFeatures { - // A map from feature to stabilisation version. - pub stable: FxHashMap, - pub unstable: FxHashSet, -} - -impl LibFeatures { - fn new() -> LibFeatures { - LibFeatures { stable: Default::default(), unstable: Default::default() } - } - - pub fn to_vec(&self) -> Vec<(Symbol, Option)> { - let mut all_features: Vec<_> = self - .stable - .iter() - .map(|(f, s)| (*f, Some(*s))) - .chain(self.unstable.iter().map(|f| (*f, None))) - .collect(); - all_features.sort_unstable_by_key(|f| f.0.as_str()); - all_features - } +fn new_lib_features() -> LibFeatures { + LibFeatures { stable: Default::default(), unstable: Default::default() } } pub struct LibFeatureCollector<'tcx> { @@ -45,7 +26,7 @@ pub struct LibFeatureCollector<'tcx> { impl LibFeatureCollector<'tcx> { fn new(tcx: TyCtxt<'tcx>) -> LibFeatureCollector<'tcx> { - LibFeatureCollector { tcx, lib_features: LibFeatures::new() } + LibFeatureCollector { tcx, lib_features: new_lib_features() } } fn extract(&self, attr: &Attribute) -> Option<(Symbol, Option, Span)> { @@ -142,7 +123,7 @@ impl Visitor<'tcx> for LibFeatureCollector<'tcx> { } } -pub fn collect(tcx: TyCtxt<'_>) -> LibFeatures { +fn collect(tcx: TyCtxt<'_>) -> LibFeatures { let mut collector = LibFeatureCollector::new(tcx); let krate = tcx.hir().krate(); for attr in krate.non_exported_macro_attrs { @@ -151,3 +132,10 @@ pub fn collect(tcx: TyCtxt<'_>) -> LibFeatures { intravisit::walk_crate(&mut collector, krate); collector.lib_features } + +pub fn provide(providers: &mut Providers<'_>) { + providers.get_lib_features = |tcx, id| { + assert_eq!(id, LOCAL_CRATE); + tcx.arena.alloc(collect(tcx)) + }; +} From f5c63e7b27cfb94cbc0b78ab109616c7c4706779 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 29 Dec 2019 11:57:30 +0100 Subject: [PATCH 7/7] Introduce librustc/middle/mod.rs --- src/librustc/lib.rs | 40 +------------------------------------- src/librustc/middle/mod.rs | 35 +++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 39 deletions(-) create mode 100644 src/librustc/middle/mod.rs diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 35c20cdbaf591..76588dfa5e25e 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -95,45 +95,7 @@ pub mod hir; pub mod ich; pub mod infer; pub mod lint; - -pub mod middle { - pub mod cstore; - pub mod dependency_format; - pub mod exported_symbols; - pub mod free_region; - pub mod lang_items; - pub mod lib_features { - use rustc_data_structures::fx::{FxHashMap, FxHashSet}; - use syntax::symbol::Symbol; - - #[derive(HashStable)] - pub struct LibFeatures { - // A map from feature to stabilisation version. - pub stable: FxHashMap, - pub unstable: FxHashSet, - } - - impl LibFeatures { - pub fn to_vec(&self) -> Vec<(Symbol, Option)> { - let mut all_features: Vec<_> = self - .stable - .iter() - .map(|(f, s)| (*f, Some(*s))) - .chain(self.unstable.iter().map(|f| (*f, None))) - .collect(); - all_features.sort_unstable_by_key(|f| f.0.as_str()); - all_features - } - } - } - pub mod privacy; - pub mod recursion_limit; - pub mod region; - pub mod resolve_lifetime; - pub mod stability; - pub mod weak_lang_items; -} - +pub mod middle; pub mod mir; pub use rustc_session as session; pub mod traits; diff --git a/src/librustc/middle/mod.rs b/src/librustc/middle/mod.rs new file mode 100644 index 0000000000000..030bcf3bf4231 --- /dev/null +++ b/src/librustc/middle/mod.rs @@ -0,0 +1,35 @@ +pub mod cstore; +pub mod dependency_format; +pub mod exported_symbols; +pub mod free_region; +pub mod lang_items; +pub mod lib_features { + use rustc_data_structures::fx::{FxHashMap, FxHashSet}; + use syntax::symbol::Symbol; + + #[derive(HashStable)] + pub struct LibFeatures { + // A map from feature to stabilisation version. + pub stable: FxHashMap, + pub unstable: FxHashSet, + } + + impl LibFeatures { + pub fn to_vec(&self) -> Vec<(Symbol, Option)> { + let mut all_features: Vec<_> = self + .stable + .iter() + .map(|(f, s)| (*f, Some(*s))) + .chain(self.unstable.iter().map(|f| (*f, None))) + .collect(); + all_features.sort_unstable_by_key(|f| f.0.as_str()); + all_features + } + } +} +pub mod privacy; +pub mod recursion_limit; +pub mod region; +pub mod resolve_lifetime; +pub mod stability; +pub mod weak_lang_items;