From 8925fccbd86d8d2c6dc8c745fcdba800099412c0 Mon Sep 17 00:00:00 2001 From: Robert Cunningham Date: Sat, 13 Aug 2022 15:35:24 -0400 Subject: [PATCH 01/25] hashmap compiles --- compiler/rustc_metadata/src/rmeta/decoder.rs | 21 +++++++ .../src/rmeta/decoder/cstore_impl.rs | 1 + compiler/rustc_metadata/src/rmeta/encoder.rs | 57 ++++++++++++++++++- compiler/rustc_middle/src/arena.rs | 1 + compiler/rustc_middle/src/hir/map/mod.rs | 2 + compiler/rustc_middle/src/hir/mod.rs | 2 +- compiler/rustc_middle/src/query/mod.rs | 17 +++++- compiler/rustc_middle/src/ty/trait_def.rs | 1 + src/librustdoc/core.rs | 1 + 9 files changed, 99 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 40dc4fb052d96..7753da15df4d3 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1248,6 +1248,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { self.root.traits.decode(self).map(move |index| self.local_def_id(index)) } + // robert-trait: this implements trait_impls_in_crate_untracked /// Decodes all trait impls in the crate (for rustdoc). fn get_trait_impls(self) -> impl Iterator)> + 'a { self.cdata.trait_impls.iter().flat_map(move |(&(trait_cnum_raw, trait_index), impls)| { @@ -1261,6 +1262,25 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { }) } + fn get_trait_impl_map(self) -> FxHashMap)>> { + self.cdata + .trait_impls + .iter() + .map(|(&(trait_cnum_raw, trait_index), impls)| { + let krate = self.cnum_map[CrateNum::from_u32(trait_cnum_raw)]; + let trait_def_id = DefId { krate, index: trait_index }; + + return ( + trait_def_id, + impls + .decode(self) + .map(|(impl_index, ty)| (DefId { krate, index: impl_index }, ty)) + .collect(), + ); + }) + .collect() + } + fn get_all_incoherent_impls(self) -> impl Iterator + 'a { self.cdata .incoherent_impls @@ -1276,6 +1296,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } } + // robert-trait: ultimately uses decoder.trait_impls. this is for external crates, and is used in trait_impls_of, which iterates over external crates and calls this. fn get_implementations_of_trait( self, tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 38ce50e8323b1..604bdd48455db 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -277,6 +277,7 @@ provide! { <'tcx> tcx, def_id, other, cdata, extra_filename => { cdata.root.extra_filename.clone() } traits_in_crate => { tcx.arena.alloc_from_iter(cdata.get_traits()) } + impls_in_crate => { tcx.arena.alloc(cdata.get_trait_impl_map()) } implementations_of_trait => { cdata.get_implementations_of_trait(tcx, other) } crate_incoherent_impls => { cdata.get_incoherent_impls(tcx, other) } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 33278367ce32d..ed72e5666183d 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1813,11 +1813,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.lazy_array(self.tcx.traits_in_crate(LOCAL_CRATE).iter().map(|def_id| def_id.index)) } + // robert-trait: serialize traits to meta vir HIR iteration /// Encodes an index, mapping each trait to its (local) implementations. fn encode_impls(&mut self) -> LazyArray { debug!("EncodeContext::encode_traits_and_impls()"); empty_proc_macro!(self); let tcx = self.tcx; + /* let mut fx_hash_map: FxHashMap)>> = FxHashMap::default(); @@ -1837,8 +1839,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } } } + */ + let fx_hash_map = self.tcx.impls_in_crate(LOCAL_CRATE).to_owned(); + + // let mut all_impls: Vec<(DefId, Vec<(DefId, Option>)>)> let mut all_impls: Vec<_> = fx_hash_map.into_iter().collect(); + //.map(|(trait_def_id, impls)| (trait_def_id, impls.iter().map(|(impl_def_, d)| (c.expect_local().local_def_index, d)))); // Bring everything into deterministic order for hashing all_impls.sort_by_cached_key(|&(trait_def_id, _)| tcx.def_path_hash(trait_def_id)); @@ -1848,9 +1855,16 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { .map(|(trait_def_id, mut impls)| { // Bring everything into deterministic order for hashing impls.sort_by_cached_key(|&(index, _)| { - tcx.hir().def_path_hash(LocalDefId { local_def_index: index }) + tcx.hir().def_path_hash(LocalDefId { + local_def_index: index.expect_local().local_def_index, + }) }); + let impls: Vec<_> = impls + .iter() + .map(|(def_id, ty)| (def_id.expect_local().local_def_index, *ty)) + .collect(); + TraitImpls { trait_id: (trait_def_id.krate.as_u32(), trait_def_id.index), impls: self.lazy_array(&impls), @@ -2282,6 +2296,7 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>, path: &Path) { pub fn provide(providers: &mut Providers) { *providers = Providers { + all_local_trait_impls: |tcx, ()| tcx.impls_in_crate(LOCAL_CRATE), traits_in_crate: |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); @@ -2293,10 +2308,48 @@ pub fn provide(providers: &mut Providers) { } // Bring everything into deterministic order. - traits.sort_by_cached_key(|&def_id| tcx.def_path_hash(def_id)); + // traits.sort_by_cached_key(|&def_id| tcx.def_path_hash(def_id)); + // This is not necessary, since the default order is source-code order. + // The source code is hashed into crate_hash, so if crate_hash is stable then it must be stable too. + tcx.arena.alloc_slice(&traits) }, + impls_in_crate: |tcx, cnum| { + assert_eq!(cnum, LOCAL_CRATE); + /* + let mut impls = Vec::new(); + + for id in tcx.hir().items() { + if matches!(tcx.def_kind(id.def_id), DefKind::Impl) { + impls.push(id.def_id.to_def_id()); + } + } + + tcx.arena.alloc_slice(&impls) // no need to sort, source-code order is fine. + */ + let mut fx_hash_map: FxHashMap)>> = + FxHashMap::default(); + + for id in tcx.hir().items() { + if matches!(tcx.def_kind(id.def_id), DefKind::Impl) { + if let Some(trait_ref) = tcx.impl_trait_ref(id.def_id.to_def_id()) { + let simplified_self_ty = fast_reject::simplify_type( + tcx, + trait_ref.self_ty(), + TreatParams::AsInfer, + ); + + fx_hash_map + .entry(trait_ref.def_id) + .or_default() + .push((id.def_id.to_def_id(), simplified_self_ty)); + } + } + } + + tcx.arena.alloc(fx_hash_map) + }, ..*providers } } diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index b94de537dc81e..5bbd3bb1d616c 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -77,6 +77,7 @@ macro_rules! arena_types { rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::Ty<'tcx>> >, [] all_traits: Vec, + [] trait_to_impl_map: rustc_data_structures::fx::FxHashMap>)>>, [] privacy_access_levels: rustc_middle::middle::privacy::AccessLevels, [] foreign_module: rustc_session::cstore::ForeignModule, [] foreign_modules: Vec, diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 47b04c33ec1cd..58faacc652f70 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -513,8 +513,10 @@ impl<'hir> Map<'hir> { } } + // robert-trait: ultimately provided by resolver outputs. pub fn trait_impls(self, trait_did: DefId) -> &'hir [LocalDefId] { self.tcx.all_local_trait_impls(()).get(&trait_did).map_or(&[], |xs| &xs[..]) + //self.tcx.impls_in_crate(LOCAL_CRATE).get(trait_did).map_or(&[], |xs| &xs[..]) } /// Gets the attributes on the crate. This is preferable to diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 211a614717f8b..19074b84dcb4e 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -172,7 +172,7 @@ pub fn provide(providers: &mut Providers) { } }; providers.opt_def_kind = |tcx, def_id| tcx.hir().opt_def_kind(def_id.expect_local()); - providers.all_local_trait_impls = |tcx, ()| &tcx.resolutions(()).trait_impls; + //providers.all_local_trait_impls = |tcx, ()| &tcx.resolutions(()).trait_impls; providers.expn_that_defined = |tcx, id| { let id = id.expect_local(); tcx.resolutions(()).expn_that_defined.get(&id).copied().unwrap_or(ExpnId::root()) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index d8483e7e40914..c5c069689031d 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1191,11 +1191,13 @@ rustc_queries! { } } + // robert-trait: provided by the resolver outputs. /// Return all `impl` blocks in the current crate. - query all_local_trait_impls(_: ()) -> &'tcx rustc_data_structures::fx::FxIndexMap> { + query all_local_trait_impls(_: ()) -> &'tcx rustc_data_structures::fx::FxHashMap> { desc { "local trait impls" } } + // robert-trait: this aggregates across all crates. Ultimately provided by decoder.trait_impls. /// Given a trait `trait_id`, return all known `impl` blocks. query trait_impls_of(trait_id: DefId) -> ty::trait_def::TraitImpls { storage(ArenaCacheSelector<'tcx>) @@ -1525,6 +1527,7 @@ rustc_queries! { separate_provide_extern } + // robert-trait: used for external crates. ultimately provided by decoder.trait_impls. /// Given a crate and a trait, look up all impls of that trait in the crate. /// Return `(impl_id, self_ty)`. query implementations_of_trait(_: (CrateNum, DefId)) -> &'tcx [(DefId, Option)] { @@ -1735,6 +1738,7 @@ rustc_queries! { desc { "fetching all foreign CrateNum instances" } } + // robert-trait /// A list of all traits in a crate, used by rustdoc and error reporting. /// NOTE: Not named just `traits` due to a naming conflict. query traits_in_crate(_: CrateNum) -> &'tcx [DefId] { @@ -1742,6 +1746,17 @@ rustc_queries! { separate_provide_extern } + // robert-trait + //HashMap>)> (from decoder.encode_impls) + // all_local_trait_impls: tcx FxIndexMap> + // FxIndexMap>, + /// A list of all impls in a crate. + //use rustc_middle::ty::fast_reject::SimplifiedTypeGen; + query impls_in_crate(_: CrateNum) -> &'tcx FxHashMap>)>> { + desc { "fetching trait to impl map in a crate" } + separate_provide_extern + } + /// The list of symbols exported from the given crate. /// /// - All names contained in `exported_symbols(cnum)` are guaranteed to diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index 541dace5cc2bb..f9c052f2e4e11 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -211,6 +211,7 @@ impl<'tcx> TyCtxt<'tcx> { } } +// robert-trait: ultimately provided by decoder.trait_impls // Query provider for `trait_impls_of`. pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> TraitImpls { let mut impls = TraitImpls::default(); diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index c48b25aea4a37..13bd984789051 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -142,6 +142,7 @@ impl<'tcx> DocContext<'tcx> { self.resolver_caches.all_traits = all_traits; } + // robert-trait: should this use a query? pub(crate) fn with_all_trait_impls(&mut self, f: impl FnOnce(&mut Self, &[DefId])) { let all_trait_impls = self.resolver_caches.all_trait_impls.take(); f(self, all_trait_impls.as_ref().expect("`all_trait_impls` are already borrowed")); From d84ecf29c287fe821bc11357dc771baab6399664 Mon Sep 17 00:00:00 2001 From: Robert Cunningham Date: Sat, 13 Aug 2022 16:05:46 -0400 Subject: [PATCH 02/25] write all_local_trait_impls in terms of new query --- compiler/rustc_metadata/src/rmeta/encoder.rs | 15 +++++- compiler/rustc_middle/src/arena.rs | 3 +- compiler/rustc_middle/src/hir/map/mod.rs | 2 +- compiler/rustc_middle/src/hir/mod.rs | 1 - compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_typeck/src/lib.rs | 1 + src/tools/clippy/clippy_lints/src/derive.rs | 50 ++++++++++++++------ 7 files changed, 54 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index ed72e5666183d..d507f85698ac9 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -2296,7 +2296,20 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>, path: &Path) { pub fn provide(providers: &mut Providers) { *providers = Providers { - all_local_trait_impls: |tcx, ()| tcx.impls_in_crate(LOCAL_CRATE), + all_local_trait_impls: |tcx, _| { + let o: FxHashMap<_, _> = tcx + .impls_in_crate(LOCAL_CRATE) + .iter() + .map(|(trait_id, impls)| { + ( + *trait_id, + impls.iter().map(|(id, _)| id.expect_local()).collect::>(), + ) + }) + .collect(); + + tcx.arena.alloc(o) + }, traits_in_crate: |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index 5bbd3bb1d616c..c57a730ef27b1 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -77,7 +77,8 @@ macro_rules! arena_types { rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::Ty<'tcx>> >, [] all_traits: Vec, - [] trait_to_impl_map: rustc_data_structures::fx::FxHashMap>)>>, + [] trait_to_impl_and_ty: rustc_data_structures::fx::FxHashMap>)>>, + [] trait_to_impl: rustc_data_structures::fx::FxHashMap>, [] privacy_access_levels: rustc_middle::middle::privacy::AccessLevels, [] foreign_module: rustc_session::cstore::ForeignModule, [] foreign_modules: Vec, diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 58faacc652f70..b9c59e216b402 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -516,7 +516,7 @@ impl<'hir> Map<'hir> { // robert-trait: ultimately provided by resolver outputs. pub fn trait_impls(self, trait_did: DefId) -> &'hir [LocalDefId] { self.tcx.all_local_trait_impls(()).get(&trait_did).map_or(&[], |xs| &xs[..]) - //self.tcx.impls_in_crate(LOCAL_CRATE).get(trait_did).map_or(&[], |xs| &xs[..]) + //self.tcx.impls_in_crate(LOCAL_CRATE).get(&trait_did).map_or(&[], |xs| &xs[..]) } /// Gets the attributes on the crate. This is preferable to diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 19074b84dcb4e..d39bceea63e09 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -172,7 +172,6 @@ pub fn provide(providers: &mut Providers) { } }; providers.opt_def_kind = |tcx, def_id| tcx.hir().opt_def_kind(def_id.expect_local()); - //providers.all_local_trait_impls = |tcx, ()| &tcx.resolutions(()).trait_impls; providers.expn_that_defined = |tcx, id| { let id = id.expect_local(); tcx.resolutions(()).expn_that_defined.get(&id).copied().unwrap_or(ExpnId::root()) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index c5c069689031d..4ec826b2127cf 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1748,7 +1748,7 @@ rustc_queries! { // robert-trait //HashMap>)> (from decoder.encode_impls) - // all_local_trait_impls: tcx FxIndexMap> + //all_local_trait_impls: tcx FxIndexMap> // FxIndexMap>, /// A list of all impls in a crate. //use rustc_middle::ty::fast_reject::SimplifiedTypeGen; diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs index 1563f3552c541..73f0b903ba28a 100644 --- a/compiler/rustc_typeck/src/lib.rs +++ b/compiler/rustc_typeck/src/lib.rs @@ -486,6 +486,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> { tcx.sess.track_errors(|| { tcx.sess.time("coherence_checking", || { for &trait_def_id in tcx.all_local_trait_impls(()).keys() { + //for &trait_def_id in tcx.impls_in_crate(()).keys() { tcx.ensure().coherent_trait(trait_def_id); } diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index a982990e4186c..b800919d230bc 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -1,4 +1,6 @@ -use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then}; +use clippy_utils::diagnostics::{ + span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then, +}; use clippy_utils::paths; use clippy_utils::ty::{implements_trait, implements_trait_with_env, is_copy}; use clippy_utils::{is_lint_allowed, match_def_path}; @@ -7,15 +9,15 @@ use rustc_errors::Applicability; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{walk_expr, walk_fn, walk_item, FnKind, Visitor}; use rustc_hir::{ - self as hir, BlockCheckMode, BodyId, Constness, Expr, ExprKind, FnDecl, HirId, Impl, Item, ItemKind, UnsafeSource, - Unsafety, + self as hir, BlockCheckMode, BodyId, Constness, Expr, ExprKind, FnDecl, HirId, Impl, Item, + ItemKind, UnsafeSource, Unsafety, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::nested_filter; use rustc_middle::traits::Reveal; use rustc_middle::ty::{ - self, Binder, BoundConstness, GenericParamDefKind, ImplPolarity, ParamEnv, PredicateKind, TraitPredicate, TraitRef, - Ty, TyCtxt, Visibility, + self, Binder, BoundConstness, GenericParamDefKind, ImplPolarity, ParamEnv, PredicateKind, + TraitPredicate, TraitRef, Ty, TyCtxt, Visibility, }; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; @@ -205,13 +207,10 @@ declare_lint_pass!(Derive => [ impl<'tcx> LateLintPass<'tcx> for Derive { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { - if let ItemKind::Impl(Impl { - of_trait: Some(ref trait_ref), - .. - }) = item.kind - { + if let ItemKind::Impl(Impl { of_trait: Some(ref trait_ref), .. }) = item.kind { let ty = cx.tcx.type_of(item.def_id); - let is_automatically_derived = cx.tcx.has_attr(item.def_id.to_def_id(), sym::automatically_derived); + let is_automatically_derived = + cx.tcx.has_attr(item.def_id.to_def_id(), sym::automatically_derived); check_hash_peq(cx, item.span, trait_ref, ty, is_automatically_derived); check_ord_partial_ord(cx, item.span, trait_ref, ty, is_automatically_derived); @@ -334,7 +333,12 @@ fn check_ord_partial_ord<'tcx>( } /// Implementation of the `EXPL_IMPL_CLONE_ON_COPY` lint. -fn check_copy_clone<'tcx>(cx: &LateContext<'tcx>, item: &Item<'_>, trait_ref: &hir::TraitRef<'_>, ty: Ty<'tcx>) { +fn check_copy_clone<'tcx>( + cx: &LateContext<'tcx>, + item: &Item<'_>, + trait_ref: &hir::TraitRef<'_>, + ty: Ty<'tcx>, +) { let clone_id = match cx.tcx.lang_items().clone_trait() { Some(id) if trait_ref.trait_def_id() == Some(id) => id, _ => return, @@ -353,6 +357,7 @@ fn check_copy_clone<'tcx>(cx: &LateContext<'tcx>, item: &Item<'_>, trait_ref: &h if !is_copy(cx, ty) { if ty_subs.non_erasable_generics().next().is_some() { let has_copy_impl = cx.tcx.all_local_trait_impls(()).get(©_id).map_or(false, |impls| { + //let has_copy_impl = cx.tcx.impls_in_crate(()).get(©_id).map_or(false, |impls| { impls .iter() .any(|&id| matches!(cx.tcx.type_of(id).kind(), ty::Adt(adt, _) if ty_adt.did() == adt.did())) @@ -425,7 +430,14 @@ struct UnsafeVisitor<'a, 'tcx> { impl<'tcx> Visitor<'tcx> for UnsafeVisitor<'_, 'tcx> { type NestedFilter = nested_filter::All; - fn visit_fn(&mut self, kind: FnKind<'tcx>, decl: &'tcx FnDecl<'_>, body_id: BodyId, span: Span, id: HirId) { + fn visit_fn( + &mut self, + kind: FnKind<'tcx>, + decl: &'tcx FnDecl<'_>, + body_id: BodyId, + span: Span, + id: HirId, + ) { if self.has_unsafe { return; } @@ -461,7 +473,12 @@ impl<'tcx> Visitor<'tcx> for UnsafeVisitor<'_, 'tcx> { } /// Implementation of the `DERIVE_PARTIAL_EQ_WITHOUT_EQ` lint. -fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_ref: &hir::TraitRef<'_>, ty: Ty<'tcx>) { +fn check_partial_eq_without_eq<'tcx>( + cx: &LateContext<'tcx>, + span: Span, + trait_ref: &hir::TraitRef<'_>, + ty: Ty<'tcx>, +) { if_chain! { if let ty::Adt(adt, substs) = ty.kind(); if cx.tcx.visibility(adt.did()) == Visibility::Public; @@ -516,7 +533,10 @@ fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) -> tcx.mk_predicates(ty_predicates.iter().map(|&(p, _)| p).chain( params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| { tcx.mk_predicate(Binder::dummy(PredicateKind::Trait(TraitPredicate { - trait_ref: TraitRef::new(eq_trait_id, tcx.mk_substs([tcx.mk_param_from_def(param)].into_iter())), + trait_ref: TraitRef::new( + eq_trait_id, + tcx.mk_substs([tcx.mk_param_from_def(param)].into_iter()), + ), constness: BoundConstness::NotConst, polarity: ImplPolarity::Positive, }))) From 8acd1455140f09613e0566227114355b5e3f5c0e Mon Sep 17 00:00:00 2001 From: Robert Cunningham Date: Sat, 13 Aug 2022 16:42:39 -0400 Subject: [PATCH 03/25] remove fom resolver --- compiler/rustc_middle/src/ty/mod.rs | 4 ++-- compiler/rustc_resolve/src/late.rs | 14 +++++++------- compiler/rustc_resolve/src/lib.rs | 8 ++++---- compiler/rustc_typeck/src/lib.rs | 1 - 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 02da02568d7e5..6d43176544796 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -29,7 +29,7 @@ use rustc_ast as ast; use rustc_ast::node_id::NodeMap; use rustc_attr as attr; use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; use rustc_data_structures::intern::{Interned, WithStableHash}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::tagged_ptr::CopyTaggedPtr; @@ -153,7 +153,7 @@ pub struct ResolverOutputs { /// via `extern crate` item and not `--extern` option or compiler built-in. pub extern_prelude: FxHashMap, pub main_def: Option, - pub trait_impls: FxIndexMap>, + //pub trait_impls: FxIndexMap>, /// A list of proc macro LocalDefIds, written out in the order in which /// they are declared in the static array generated by proc_macro_harness. pub proc_macros: Vec, diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index dea3eaecda6e7..1952e25f0060c 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2621,13 +2621,13 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { let item_def_id = this.r.local_def_id(item_id); // Register the trait definitions from here. - if let Some(trait_id) = trait_id { - this.r - .trait_impls - .entry(trait_id) - .or_default() - .push(item_def_id); - } + //if let Some(trait_id) = trait_id { + // this.r + // .trait_impls + // .entry(trait_id) + // .or_default() + // .push(item_def_id); + //} let item_def_id = item_def_id.to_def_id(); let res = Res::SelfTy { diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index ef3c3da89c572..38863c9f6c596 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1048,7 +1048,7 @@ pub struct Resolver<'a> { item_generics_num_lifetimes: FxHashMap, main_def: Option, - trait_impls: FxIndexMap>, + //trait_impls: FxIndexMap>, /// A list of proc macro LocalDefIds, written out in the order in which /// they are declared in the static array generated by proc_macro_harness. proc_macros: Vec, @@ -1358,7 +1358,7 @@ impl<'a> Resolver<'a> { legacy_const_generic_args: Default::default(), item_generics_num_lifetimes: Default::default(), main_def: Default::default(), - trait_impls: Default::default(), + //trait_impls: Default::default(), proc_macros: Default::default(), confused_type_with_std_module: Default::default(), access_levels: Default::default(), @@ -1439,7 +1439,7 @@ impl<'a> Resolver<'a> { .map(|(ident, entry)| (ident.name, entry.introduced_by_item)) .collect(), main_def, - trait_impls: self.trait_impls, + //trait_impls: self.trait_impls, proc_macros, confused_type_with_std_module, registered_tools: self.registered_tools, @@ -1483,7 +1483,7 @@ impl<'a> Resolver<'a> { .map(|(ident, entry)| (ident.name, entry.introduced_by_item)) .collect(), main_def: self.main_def, - trait_impls: self.trait_impls.clone(), + //trait_impls: self.trait_impls.clone(), proc_macros, confused_type_with_std_module: self.confused_type_with_std_module.clone(), registered_tools: self.registered_tools.clone(), diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs index 73f0b903ba28a..1563f3552c541 100644 --- a/compiler/rustc_typeck/src/lib.rs +++ b/compiler/rustc_typeck/src/lib.rs @@ -486,7 +486,6 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> { tcx.sess.track_errors(|| { tcx.sess.time("coherence_checking", || { for &trait_def_id in tcx.all_local_trait_impls(()).keys() { - //for &trait_def_id in tcx.impls_in_crate(()).keys() { tcx.ensure().coherent_trait(trait_def_id); } From 2d54ab7770013c59c2eee1f95fa978ed0b764981 Mon Sep 17 00:00:00 2001 From: Robert Cunningham Date: Sun, 14 Aug 2022 00:52:56 -0400 Subject: [PATCH 04/25] convert hashmap to indexmap --- compiler/rustc_incremental/src/assert_dep_graph.rs | 5 ++++- compiler/rustc_metadata/src/rmeta/decoder.rs | 4 ++-- compiler/rustc_metadata/src/rmeta/encoder.rs | 8 ++++---- compiler/rustc_middle/src/arena.rs | 4 ++-- compiler/rustc_middle/src/query/mod.rs | 4 ++-- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_incremental/src/assert_dep_graph.rs b/compiler/rustc_incremental/src/assert_dep_graph.rs index 69e482ce854c0..ac4a762d0a962 100644 --- a/compiler/rustc_incremental/src/assert_dep_graph.rs +++ b/compiler/rustc_incremental/src/assert_dep_graph.rs @@ -54,8 +54,11 @@ use std::io::{BufWriter, Write}; #[allow(missing_docs)] pub fn assert_dep_graph(tcx: TyCtxt<'_>) { + println!("demping dep graph 1!!"); tcx.dep_graph.with_ignore(|| { - if tcx.sess.opts.unstable_opts.dump_dep_graph { + println!("demping dep graph 2!!"); + if tcx.sess.opts.unstable_opts.dump_dep_graph || true { + println!("demping dep graph 3!!"); tcx.dep_graph.with_query(dump_graph); } diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 7753da15df4d3..e4c40098cde49 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -6,7 +6,7 @@ use crate::rmeta::*; use rustc_ast as ast; use rustc_ast::ptr::P; use rustc_data_structures::captures::Captures; -use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::{Lock, LockGuard, Lrc, OnceCell}; use rustc_data_structures::unhash::UnhashMap; @@ -1262,7 +1262,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { }) } - fn get_trait_impl_map(self) -> FxHashMap)>> { + fn get_trait_impl_map(self) -> FxIndexMap)>> { self.cdata .trait_impls .iter() diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index d507f85698ac9..dfae02ba5393c 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -3,7 +3,7 @@ use crate::rmeta::table::TableBuilder; use crate::rmeta::*; use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; +use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet}; use rustc_data_structures::memmap::{Mmap, MmapMut}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{join, par_iter, Lrc, ParallelIterator}; @@ -2297,7 +2297,7 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>, path: &Path) { pub fn provide(providers: &mut Providers) { *providers = Providers { all_local_trait_impls: |tcx, _| { - let o: FxHashMap<_, _> = tcx + let o: FxIndexMap<_, _> = tcx .impls_in_crate(LOCAL_CRATE) .iter() .map(|(trait_id, impls)| { @@ -2341,8 +2341,8 @@ pub fn provide(providers: &mut Providers) { tcx.arena.alloc_slice(&impls) // no need to sort, source-code order is fine. */ - let mut fx_hash_map: FxHashMap)>> = - FxHashMap::default(); + let mut fx_hash_map: FxIndexMap)>> = + FxIndexMap::default(); for id in tcx.hir().items() { if matches!(tcx.def_kind(id.def_id), DefKind::Impl) { diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index c57a730ef27b1..5ffce5d4ca5fe 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -77,8 +77,8 @@ macro_rules! arena_types { rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::Ty<'tcx>> >, [] all_traits: Vec, - [] trait_to_impl_and_ty: rustc_data_structures::fx::FxHashMap>)>>, - [] trait_to_impl: rustc_data_structures::fx::FxHashMap>, + [] trait_to_impl_and_ty: rustc_data_structures::fx::FxIndexMap>)>>, + [] trait_to_impl: rustc_data_structures::fx::FxIndexMap>, [] privacy_access_levels: rustc_middle::middle::privacy::AccessLevels, [] foreign_module: rustc_session::cstore::ForeignModule, [] foreign_modules: Vec, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 4ec826b2127cf..4c02630ec2f7c 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1193,7 +1193,7 @@ rustc_queries! { // robert-trait: provided by the resolver outputs. /// Return all `impl` blocks in the current crate. - query all_local_trait_impls(_: ()) -> &'tcx rustc_data_structures::fx::FxHashMap> { + query all_local_trait_impls(_: ()) -> &'tcx rustc_data_structures::fx::FxIndexMap> { desc { "local trait impls" } } @@ -1752,7 +1752,7 @@ rustc_queries! { // FxIndexMap>, /// A list of all impls in a crate. //use rustc_middle::ty::fast_reject::SimplifiedTypeGen; - query impls_in_crate(_: CrateNum) -> &'tcx FxHashMap>)>> { + query impls_in_crate(_: CrateNum) -> &'tcx FxIndexMap>)>> { desc { "fetching trait to impl map in a crate" } separate_provide_extern } From ab7c2ba73707058a2d80f854a33565e511c3a205 Mon Sep 17 00:00:00 2001 From: Robert Cunningham Date: Mon, 15 Aug 2022 13:36:29 -0400 Subject: [PATCH 05/25] add eval_always --- compiler/rustc_incremental/src/assert_dep_graph.rs | 3 --- compiler/rustc_metadata/src/rmeta/encoder.rs | 13 ++++++++++++- compiler/rustc_middle/src/hir/mod.rs | 2 ++ compiler/rustc_middle/src/query/mod.rs | 2 ++ compiler/rustc_resolve/src/late.rs | 1 + 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_incremental/src/assert_dep_graph.rs b/compiler/rustc_incremental/src/assert_dep_graph.rs index ac4a762d0a962..8e2d937351366 100644 --- a/compiler/rustc_incremental/src/assert_dep_graph.rs +++ b/compiler/rustc_incremental/src/assert_dep_graph.rs @@ -54,11 +54,8 @@ use std::io::{BufWriter, Write}; #[allow(missing_docs)] pub fn assert_dep_graph(tcx: TyCtxt<'_>) { - println!("demping dep graph 1!!"); tcx.dep_graph.with_ignore(|| { - println!("demping dep graph 2!!"); if tcx.sess.opts.unstable_opts.dump_dep_graph || true { - println!("demping dep graph 3!!"); tcx.dep_graph.with_query(dump_graph); } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index dfae02ba5393c..189082341a00f 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -2297,6 +2297,11 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>, path: &Path) { pub fn provide(providers: &mut Providers) { *providers = Providers { all_local_trait_impls: |tcx, _| { + // with just top live, error. + // with just bottom live, success. + // with both live, fails. + // so although the top has no impact on the output, it causes the failure. + let o: FxIndexMap<_, _> = tcx .impls_in_crate(LOCAL_CRATE) .iter() @@ -2309,6 +2314,9 @@ pub fn provide(providers: &mut Providers) { .collect(); tcx.arena.alloc(o) + + //providers.all_local_trait_impls = |tcx, ()| &tcx.resolutions(()).trait_impls; + //&tcx.resolutions(()).trait_impls }, traits_in_crate: |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); @@ -2316,12 +2324,13 @@ pub fn provide(providers: &mut Providers) { let mut traits = Vec::new(); for id in tcx.hir().items() { if matches!(tcx.def_kind(id.def_id), DefKind::Trait | DefKind::TraitAlias) { + //println!("matches b"); traits.push(id.def_id.to_def_id()) } } // Bring everything into deterministic order. - // traits.sort_by_cached_key(|&def_id| tcx.def_path_hash(def_id)); + //traits.sort_by_cached_key(|&def_id| tcx.def_path_hash(def_id)); // This is not necessary, since the default order is source-code order. // The source code is hashed into crate_hash, so if crate_hash is stable then it must be stable too. @@ -2345,7 +2354,9 @@ pub fn provide(providers: &mut Providers) { FxIndexMap::default(); for id in tcx.hir().items() { + //println!("{:?}", id); if matches!(tcx.def_kind(id.def_id), DefKind::Impl) { + //println!("matches a"); if let Some(trait_ref) = tcx.impl_trait_ref(id.def_id.to_def_id()) { let simplified_self_ty = fast_reject::simplify_type( tcx, diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index d39bceea63e09..7d1d7e0775e7a 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -172,6 +172,8 @@ pub fn provide(providers: &mut Providers) { } }; providers.opt_def_kind = |tcx, def_id| tcx.hir().opt_def_kind(def_id.expect_local()); + // robert-resolver + //providers.all_local_trait_impls = |tcx, ()| &tcx.resolutions(()).trait_impls; providers.expn_that_defined = |tcx, id| { let id = id.expect_local(); tcx.resolutions(()).expn_that_defined.get(&id).copied().unwrap_or(ExpnId::root()) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 4c02630ec2f7c..b4220498b06fb 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1742,6 +1742,7 @@ rustc_queries! { /// A list of all traits in a crate, used by rustdoc and error reporting. /// NOTE: Not named just `traits` due to a naming conflict. query traits_in_crate(_: CrateNum) -> &'tcx [DefId] { + eval_always desc { "fetching all traits in a crate" } separate_provide_extern } @@ -1753,6 +1754,7 @@ rustc_queries! { /// A list of all impls in a crate. //use rustc_middle::ty::fast_reject::SimplifiedTypeGen; query impls_in_crate(_: CrateNum) -> &'tcx FxIndexMap>)>> { + eval_always desc { "fetching trait to impl map in a crate" } separate_provide_extern } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 1952e25f0060c..ad06e02a96c2f 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2621,6 +2621,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { let item_def_id = this.r.local_def_id(item_id); // Register the trait definitions from here. + // robert-resolver //if let Some(trait_id) = trait_id { // this.r // .trait_impls From d3426ddd66654350bd11dc77a4746db380619bea Mon Sep 17 00:00:00 2001 From: Robert Cunningham Date: Mon, 15 Aug 2022 13:52:54 -0400 Subject: [PATCH 06/25] stop prinnting dep graph --- compiler/rustc_incremental/src/assert_dep_graph.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_incremental/src/assert_dep_graph.rs b/compiler/rustc_incremental/src/assert_dep_graph.rs index 8e2d937351366..69e482ce854c0 100644 --- a/compiler/rustc_incremental/src/assert_dep_graph.rs +++ b/compiler/rustc_incremental/src/assert_dep_graph.rs @@ -55,7 +55,7 @@ use std::io::{BufWriter, Write}; #[allow(missing_docs)] pub fn assert_dep_graph(tcx: TyCtxt<'_>) { tcx.dep_graph.with_ignore(|| { - if tcx.sess.opts.unstable_opts.dump_dep_graph || true { + if tcx.sess.opts.unstable_opts.dump_dep_graph { tcx.dep_graph.with_query(dump_graph); } From 251fcbcecb1581ad36d562095329540ac9422bfa Mon Sep 17 00:00:00 2001 From: Robert Cunningham Date: Mon, 15 Aug 2022 14:49:45 -0400 Subject: [PATCH 07/25] clean up --- compiler/rustc_metadata/src/rmeta/decoder.rs | 3 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 52 +------------------- compiler/rustc_middle/src/hir/map/mod.rs | 2 - compiler/rustc_middle/src/hir/mod.rs | 2 - compiler/rustc_middle/src/ty/mod.rs | 1 - compiler/rustc_middle/src/ty/trait_def.rs | 1 - compiler/rustc_resolve/src/late.rs | 10 ---- compiler/rustc_resolve/src/lib.rs | 4 -- 8 files changed, 2 insertions(+), 73 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index e4c40098cde49..2a7c482374a3a 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1248,7 +1248,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { self.root.traits.decode(self).map(move |index| self.local_def_id(index)) } - // robert-trait: this implements trait_impls_in_crate_untracked /// Decodes all trait impls in the crate (for rustdoc). fn get_trait_impls(self) -> impl Iterator)> + 'a { self.cdata.trait_impls.iter().flat_map(move |(&(trait_cnum_raw, trait_index), impls)| { @@ -1262,6 +1261,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { }) } + /// Decodes a map from trait to impls. fn get_trait_impl_map(self) -> FxIndexMap)>> { self.cdata .trait_impls @@ -1296,7 +1296,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } } - // robert-trait: ultimately uses decoder.trait_impls. this is for external crates, and is used in trait_impls_of, which iterates over external crates and calls this. fn get_implementations_of_trait( self, tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 189082341a00f..946ed3550a2f6 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1813,39 +1813,14 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.lazy_array(self.tcx.traits_in_crate(LOCAL_CRATE).iter().map(|def_id| def_id.index)) } - // robert-trait: serialize traits to meta vir HIR iteration /// Encodes an index, mapping each trait to its (local) implementations. fn encode_impls(&mut self) -> LazyArray { debug!("EncodeContext::encode_traits_and_impls()"); empty_proc_macro!(self); let tcx = self.tcx; - /* - let mut fx_hash_map: FxHashMap)>> = - FxHashMap::default(); - - for id in tcx.hir().items() { - if matches!(tcx.def_kind(id.def_id), DefKind::Impl) { - if let Some(trait_ref) = tcx.impl_trait_ref(id.def_id.to_def_id()) { - let simplified_self_ty = fast_reject::simplify_type( - self.tcx, - trait_ref.self_ty(), - TreatParams::AsInfer, - ); - - fx_hash_map - .entry(trait_ref.def_id) - .or_default() - .push((id.def_id.local_def_index, simplified_self_ty)); - } - } - } - */ - let fx_hash_map = self.tcx.impls_in_crate(LOCAL_CRATE).to_owned(); - // let mut all_impls: Vec<(DefId, Vec<(DefId, Option>)>)> let mut all_impls: Vec<_> = fx_hash_map.into_iter().collect(); - //.map(|(trait_def_id, impls)| (trait_def_id, impls.iter().map(|(impl_def_, d)| (c.expect_local().local_def_index, d)))); // Bring everything into deterministic order for hashing all_impls.sort_by_cached_key(|&(trait_def_id, _)| tcx.def_path_hash(trait_def_id)); @@ -2297,11 +2272,6 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>, path: &Path) { pub fn provide(providers: &mut Providers) { *providers = Providers { all_local_trait_impls: |tcx, _| { - // with just top live, error. - // with just bottom live, success. - // with both live, fails. - // so although the top has no impact on the output, it causes the failure. - let o: FxIndexMap<_, _> = tcx .impls_in_crate(LOCAL_CRATE) .iter() @@ -2314,9 +2284,6 @@ pub fn provide(providers: &mut Providers) { .collect(); tcx.arena.alloc(o) - - //providers.all_local_trait_impls = |tcx, ()| &tcx.resolutions(()).trait_impls; - //&tcx.resolutions(()).trait_impls }, traits_in_crate: |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); @@ -2324,39 +2291,22 @@ pub fn provide(providers: &mut Providers) { let mut traits = Vec::new(); for id in tcx.hir().items() { if matches!(tcx.def_kind(id.def_id), DefKind::Trait | DefKind::TraitAlias) { - //println!("matches b"); traits.push(id.def_id.to_def_id()) } } - // Bring everything into deterministic order. - //traits.sort_by_cached_key(|&def_id| tcx.def_path_hash(def_id)); - // This is not necessary, since the default order is source-code order. + // We don't need to sort, since the default order is source-code order. // The source code is hashed into crate_hash, so if crate_hash is stable then it must be stable too. tcx.arena.alloc_slice(&traits) }, impls_in_crate: |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); - - /* - let mut impls = Vec::new(); - - for id in tcx.hir().items() { - if matches!(tcx.def_kind(id.def_id), DefKind::Impl) { - impls.push(id.def_id.to_def_id()); - } - } - - tcx.arena.alloc_slice(&impls) // no need to sort, source-code order is fine. - */ let mut fx_hash_map: FxIndexMap)>> = FxIndexMap::default(); for id in tcx.hir().items() { - //println!("{:?}", id); if matches!(tcx.def_kind(id.def_id), DefKind::Impl) { - //println!("matches a"); if let Some(trait_ref) = tcx.impl_trait_ref(id.def_id.to_def_id()) { let simplified_self_ty = fast_reject::simplify_type( tcx, diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index b9c59e216b402..47b04c33ec1cd 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -513,10 +513,8 @@ impl<'hir> Map<'hir> { } } - // robert-trait: ultimately provided by resolver outputs. pub fn trait_impls(self, trait_did: DefId) -> &'hir [LocalDefId] { self.tcx.all_local_trait_impls(()).get(&trait_did).map_or(&[], |xs| &xs[..]) - //self.tcx.impls_in_crate(LOCAL_CRATE).get(&trait_did).map_or(&[], |xs| &xs[..]) } /// Gets the attributes on the crate. This is preferable to diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 7d1d7e0775e7a..d39bceea63e09 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -172,8 +172,6 @@ pub fn provide(providers: &mut Providers) { } }; providers.opt_def_kind = |tcx, def_id| tcx.hir().opt_def_kind(def_id.expect_local()); - // robert-resolver - //providers.all_local_trait_impls = |tcx, ()| &tcx.resolutions(()).trait_impls; providers.expn_that_defined = |tcx, id| { let id = id.expect_local(); tcx.resolutions(()).expn_that_defined.get(&id).copied().unwrap_or(ExpnId::root()) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 6d43176544796..0c12f70865814 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -153,7 +153,6 @@ pub struct ResolverOutputs { /// via `extern crate` item and not `--extern` option or compiler built-in. pub extern_prelude: FxHashMap, pub main_def: Option, - //pub trait_impls: FxIndexMap>, /// A list of proc macro LocalDefIds, written out in the order in which /// they are declared in the static array generated by proc_macro_harness. pub proc_macros: Vec, diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index f9c052f2e4e11..541dace5cc2bb 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -211,7 +211,6 @@ impl<'tcx> TyCtxt<'tcx> { } } -// robert-trait: ultimately provided by decoder.trait_impls // Query provider for `trait_impls_of`. pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> TraitImpls { let mut impls = TraitImpls::default(); diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index ad06e02a96c2f..d1ca9abe96835 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2620,16 +2620,6 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { |this, trait_id| { let item_def_id = this.r.local_def_id(item_id); - // Register the trait definitions from here. - // robert-resolver - //if let Some(trait_id) = trait_id { - // this.r - // .trait_impls - // .entry(trait_id) - // .or_default() - // .push(item_def_id); - //} - let item_def_id = item_def_id.to_def_id(); let res = Res::SelfTy { trait_: trait_id, diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 38863c9f6c596..28ce8ee8e18dc 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1048,7 +1048,6 @@ pub struct Resolver<'a> { item_generics_num_lifetimes: FxHashMap, main_def: Option, - //trait_impls: FxIndexMap>, /// A list of proc macro LocalDefIds, written out in the order in which /// they are declared in the static array generated by proc_macro_harness. proc_macros: Vec, @@ -1358,7 +1357,6 @@ impl<'a> Resolver<'a> { legacy_const_generic_args: Default::default(), item_generics_num_lifetimes: Default::default(), main_def: Default::default(), - //trait_impls: Default::default(), proc_macros: Default::default(), confused_type_with_std_module: Default::default(), access_levels: Default::default(), @@ -1439,7 +1437,6 @@ impl<'a> Resolver<'a> { .map(|(ident, entry)| (ident.name, entry.introduced_by_item)) .collect(), main_def, - //trait_impls: self.trait_impls, proc_macros, confused_type_with_std_module, registered_tools: self.registered_tools, @@ -1483,7 +1480,6 @@ impl<'a> Resolver<'a> { .map(|(ident, entry)| (ident.name, entry.introduced_by_item)) .collect(), main_def: self.main_def, - //trait_impls: self.trait_impls.clone(), proc_macros, confused_type_with_std_module: self.confused_type_with_std_module.clone(), registered_tools: self.registered_tools.clone(), From 83ca511f57990fe764cb9f68e5a68b17e59217cb Mon Sep 17 00:00:00 2001 From: Robert Cunningham Date: Mon, 15 Aug 2022 16:09:41 -0400 Subject: [PATCH 08/25] revert derive formatting changes --- src/tools/clippy/clippy_lints/src/derive.rs | 50 +++++++-------------- 1 file changed, 15 insertions(+), 35 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index b800919d230bc..a982990e4186c 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -1,6 +1,4 @@ -use clippy_utils::diagnostics::{ - span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then, -}; +use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then}; use clippy_utils::paths; use clippy_utils::ty::{implements_trait, implements_trait_with_env, is_copy}; use clippy_utils::{is_lint_allowed, match_def_path}; @@ -9,15 +7,15 @@ use rustc_errors::Applicability; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{walk_expr, walk_fn, walk_item, FnKind, Visitor}; use rustc_hir::{ - self as hir, BlockCheckMode, BodyId, Constness, Expr, ExprKind, FnDecl, HirId, Impl, Item, - ItemKind, UnsafeSource, Unsafety, + self as hir, BlockCheckMode, BodyId, Constness, Expr, ExprKind, FnDecl, HirId, Impl, Item, ItemKind, UnsafeSource, + Unsafety, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::nested_filter; use rustc_middle::traits::Reveal; use rustc_middle::ty::{ - self, Binder, BoundConstness, GenericParamDefKind, ImplPolarity, ParamEnv, PredicateKind, - TraitPredicate, TraitRef, Ty, TyCtxt, Visibility, + self, Binder, BoundConstness, GenericParamDefKind, ImplPolarity, ParamEnv, PredicateKind, TraitPredicate, TraitRef, + Ty, TyCtxt, Visibility, }; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; @@ -207,10 +205,13 @@ declare_lint_pass!(Derive => [ impl<'tcx> LateLintPass<'tcx> for Derive { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { - if let ItemKind::Impl(Impl { of_trait: Some(ref trait_ref), .. }) = item.kind { + if let ItemKind::Impl(Impl { + of_trait: Some(ref trait_ref), + .. + }) = item.kind + { let ty = cx.tcx.type_of(item.def_id); - let is_automatically_derived = - cx.tcx.has_attr(item.def_id.to_def_id(), sym::automatically_derived); + let is_automatically_derived = cx.tcx.has_attr(item.def_id.to_def_id(), sym::automatically_derived); check_hash_peq(cx, item.span, trait_ref, ty, is_automatically_derived); check_ord_partial_ord(cx, item.span, trait_ref, ty, is_automatically_derived); @@ -333,12 +334,7 @@ fn check_ord_partial_ord<'tcx>( } /// Implementation of the `EXPL_IMPL_CLONE_ON_COPY` lint. -fn check_copy_clone<'tcx>( - cx: &LateContext<'tcx>, - item: &Item<'_>, - trait_ref: &hir::TraitRef<'_>, - ty: Ty<'tcx>, -) { +fn check_copy_clone<'tcx>(cx: &LateContext<'tcx>, item: &Item<'_>, trait_ref: &hir::TraitRef<'_>, ty: Ty<'tcx>) { let clone_id = match cx.tcx.lang_items().clone_trait() { Some(id) if trait_ref.trait_def_id() == Some(id) => id, _ => return, @@ -357,7 +353,6 @@ fn check_copy_clone<'tcx>( if !is_copy(cx, ty) { if ty_subs.non_erasable_generics().next().is_some() { let has_copy_impl = cx.tcx.all_local_trait_impls(()).get(©_id).map_or(false, |impls| { - //let has_copy_impl = cx.tcx.impls_in_crate(()).get(©_id).map_or(false, |impls| { impls .iter() .any(|&id| matches!(cx.tcx.type_of(id).kind(), ty::Adt(adt, _) if ty_adt.did() == adt.did())) @@ -430,14 +425,7 @@ struct UnsafeVisitor<'a, 'tcx> { impl<'tcx> Visitor<'tcx> for UnsafeVisitor<'_, 'tcx> { type NestedFilter = nested_filter::All; - fn visit_fn( - &mut self, - kind: FnKind<'tcx>, - decl: &'tcx FnDecl<'_>, - body_id: BodyId, - span: Span, - id: HirId, - ) { + fn visit_fn(&mut self, kind: FnKind<'tcx>, decl: &'tcx FnDecl<'_>, body_id: BodyId, span: Span, id: HirId) { if self.has_unsafe { return; } @@ -473,12 +461,7 @@ impl<'tcx> Visitor<'tcx> for UnsafeVisitor<'_, 'tcx> { } /// Implementation of the `DERIVE_PARTIAL_EQ_WITHOUT_EQ` lint. -fn check_partial_eq_without_eq<'tcx>( - cx: &LateContext<'tcx>, - span: Span, - trait_ref: &hir::TraitRef<'_>, - ty: Ty<'tcx>, -) { +fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_ref: &hir::TraitRef<'_>, ty: Ty<'tcx>) { if_chain! { if let ty::Adt(adt, substs) = ty.kind(); if cx.tcx.visibility(adt.did()) == Visibility::Public; @@ -533,10 +516,7 @@ fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) -> tcx.mk_predicates(ty_predicates.iter().map(|&(p, _)| p).chain( params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| { tcx.mk_predicate(Binder::dummy(PredicateKind::Trait(TraitPredicate { - trait_ref: TraitRef::new( - eq_trait_id, - tcx.mk_substs([tcx.mk_param_from_def(param)].into_iter()), - ), + trait_ref: TraitRef::new(eq_trait_id, tcx.mk_substs([tcx.mk_param_from_def(param)].into_iter())), constness: BoundConstness::NotConst, polarity: ImplPolarity::Positive, }))) From 31222def3642de85f52a7b069fcae773d4542c02 Mon Sep 17 00:00:00 2001 From: Robert Cunningham Date: Mon, 15 Aug 2022 16:17:20 -0400 Subject: [PATCH 09/25] remove comments --- compiler/rustc_middle/src/query/mod.rs | 12 +----------- compiler/rustc_resolve/src/late.rs | 4 +--- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index b4220498b06fb..9bc7c2a635397 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1191,13 +1191,11 @@ rustc_queries! { } } - // robert-trait: provided by the resolver outputs. /// Return all `impl` blocks in the current crate. query all_local_trait_impls(_: ()) -> &'tcx rustc_data_structures::fx::FxIndexMap> { desc { "local trait impls" } } - // robert-trait: this aggregates across all crates. Ultimately provided by decoder.trait_impls. /// Given a trait `trait_id`, return all known `impl` blocks. query trait_impls_of(trait_id: DefId) -> ty::trait_def::TraitImpls { storage(ArenaCacheSelector<'tcx>) @@ -1527,7 +1525,6 @@ rustc_queries! { separate_provide_extern } - // robert-trait: used for external crates. ultimately provided by decoder.trait_impls. /// Given a crate and a trait, look up all impls of that trait in the crate. /// Return `(impl_id, self_ty)`. query implementations_of_trait(_: (CrateNum, DefId)) -> &'tcx [(DefId, Option)] { @@ -1738,21 +1735,14 @@ rustc_queries! { desc { "fetching all foreign CrateNum instances" } } - // robert-trait /// A list of all traits in a crate, used by rustdoc and error reporting. /// NOTE: Not named just `traits` due to a naming conflict. query traits_in_crate(_: CrateNum) -> &'tcx [DefId] { - eval_always desc { "fetching all traits in a crate" } separate_provide_extern } - // robert-trait - //HashMap>)> (from decoder.encode_impls) - //all_local_trait_impls: tcx FxIndexMap> - // FxIndexMap>, - /// A list of all impls in a crate. - //use rustc_middle::ty::fast_reject::SimplifiedTypeGen; + /// A list of all traits in a crate mapped to their impls in that crate. query impls_in_crate(_: CrateNum) -> &'tcx FxIndexMap>)>> { eval_always desc { "fetching trait to impl map in a crate" } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index d1ca9abe96835..ec1a34c262117 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2618,9 +2618,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { opt_trait_reference.as_ref(), self_type, |this, trait_id| { - let item_def_id = this.r.local_def_id(item_id); - - let item_def_id = item_def_id.to_def_id(); + let item_def_id = this.r.local_def_id(item_id).to_def_id(); let res = Res::SelfTy { trait_: trait_id, alias_to: Some((item_def_id, false)), From 5a7d801f3b4fabcf80cd7ca1713d06a53742822c Mon Sep 17 00:00:00 2001 From: Robert Cunningham Date: Mon, 15 Aug 2022 16:29:39 -0400 Subject: [PATCH 10/25] remove last robert-trait annotation --- src/librustdoc/core.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 13bd984789051..c48b25aea4a37 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -142,7 +142,6 @@ impl<'tcx> DocContext<'tcx> { self.resolver_caches.all_traits = all_traits; } - // robert-trait: should this use a query? pub(crate) fn with_all_trait_impls(&mut self, f: impl FnOnce(&mut Self, &[DefId])) { let all_trait_impls = self.resolver_caches.all_trait_impls.take(); f(self, all_trait_impls.as_ref().expect("`all_trait_impls` are already borrowed")); From 058b8dcd8945129d43709d34e387041dd67f77ac Mon Sep 17 00:00:00 2001 From: Robert Cunningham Date: Mon, 12 Sep 2022 00:18:49 -0400 Subject: [PATCH 11/25] implement cjg first suggestion --- compiler/rustc_typeck/src/coherence/inherent_impls.rs | 10 +++++----- .../src/coherence/inherent_impls_overlap.rs | 5 +++++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_typeck/src/coherence/inherent_impls.rs b/compiler/rustc_typeck/src/coherence/inherent_impls.rs index 52aad636fd88a..cf1eb5e6fc9c7 100644 --- a/compiler/rustc_typeck/src/coherence/inherent_impls.rs +++ b/compiler/rustc_typeck/src/coherence/inherent_impls.rs @@ -7,9 +7,10 @@ //! `tcx.inherent_impls(def_id)`). That value, however, //! is computed by selecting an idea from this table. +//use hir::def_id::LOCAL_CRATE; +//use hir::ItemId; use rustc_errors::struct_span_err; use rustc_hir as hir; -use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId}; use rustc_middle::ty::fast_reject::{simplify_type, SimplifiedType, TreatParams}; use rustc_middle::ty::{self, CrateInherentImpls, Ty, TyCtxt}; @@ -19,6 +20,9 @@ use rustc_span::Span; /// On-demand query: yields a map containing all types mapped to their inherent impls. pub fn crate_inherent_impls(tcx: TyCtxt<'_>, (): ()) -> CrateInherentImpls { let mut collect = InherentCollect { tcx, impls_map: Default::default() }; + //for (id, _) in tcx.impls_in_crate(LOCAL_CRATE).values().flatten() { + // collect.check_item(ItemId { def_id: id.to_owned().expect_local() }); + //} for id in tcx.hir().items() { collect.check_item(id); } @@ -177,10 +181,6 @@ impl<'tcx> InherentCollect<'tcx> { } fn check_item(&mut self, id: hir::ItemId) { - if !matches!(self.tcx.def_kind(id.def_id), DefKind::Impl) { - return; - } - let item = self.tcx.hir().item(id); let hir::ItemKind::Impl(hir::Impl { of_trait: None, self_ty: ty, ref items, .. }) = item.kind else { return; diff --git a/compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs index 03e076bf5ec89..9250ba3fe423e 100644 --- a/compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs +++ b/compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs @@ -1,3 +1,5 @@ +use hir::def_id::LOCAL_CRATE; +use hir::ItemId; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::struct_span_err; use rustc_hir as hir; @@ -13,6 +15,9 @@ use std::collections::hash_map::Entry; pub fn crate_inherent_impls_overlap_check(tcx: TyCtxt<'_>, (): ()) { let mut inherent_overlap_checker = InherentOverlapChecker { tcx }; + //for (id, _) in tcx.impls_in_crate(LOCAL_CRATE).values().flatten() { + // inherent_overlap_checker.check_item(ItemId { def_id: id.to_owned().expect_local() }); + //} for id in tcx.hir().items() { inherent_overlap_checker.check_item(id); } From 6b0ab188cc50c3e0ec3446f993e0c98752996ab0 Mon Sep 17 00:00:00 2001 From: Robert Cunningham Date: Fri, 13 Jan 2023 02:52:47 -0500 Subject: [PATCH 12/25] temporary changed found january --- compiler/rustc_metadata/src/rmeta/encoder.rs | 41 ++++++++++--------- .../src/coherence/inherent_impls.rs | 11 +++-- .../src/coherence/inherent_impls_overlap.rs | 13 ++++-- 3 files changed, 39 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 748f7251cb90c..0e67d0047a6de 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -3,10 +3,10 @@ use crate::rmeta::def_path_hash_map::DefPathHashMapRef; use crate::rmeta::table::TableBuilder; use crate::rmeta::*; -use rustc_data_structures::fingerprint::Fingerprint; +//use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet}; use rustc_data_structures::memmap::{Mmap, MmapMut}; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_data_structures::stable_hasher::StableHasher; use rustc_data_structures::sync::{join, par_iter, Lrc, ParallelIterator}; use rustc_data_structures::temp_dir::MaybeTempDir; use rustc_hir as hir; @@ -1895,23 +1895,25 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_impls(&mut self) -> LazyArray { debug!("EncodeContext::encode_traits_and_impls()"); empty_proc_macro!(self); - let tcx = self.tcx; + //let tcx = self.tcx; let fx_hash_map = self.tcx.impls_in_crate(LOCAL_CRATE).to_owned(); - let mut all_impls: Vec<_> = fx_hash_map.into_iter().collect(); + let all_impls: Vec<_> = fx_hash_map.into_iter().collect(); // Bring everything into deterministic order for hashing - all_impls.sort_by_cached_key(|&(trait_def_id, _)| tcx.def_path_hash(trait_def_id)); + // SORT-TEST + //all_impls.sort_by_cached_key(|&(trait_def_id, _)| tcx.def_path_hash(trait_def_id)); let all_impls: Vec<_> = all_impls .into_iter() - .map(|(trait_def_id, mut impls)| { + .map(|(trait_def_id, impls)| { // Bring everything into deterministic order for hashing - impls.sort_by_cached_key(|&(index, _)| { - tcx.hir().def_path_hash(LocalDefId { - local_def_index: index.expect_local().local_def_index, - }) - }); + // SORT-TEST + //impls.sort_by_cached_key(|&(index, _)| { + // tcx.hir().def_path_hash(LocalDefId { + // local_def_index: index.expect_local().local_def_index, + // }) + //}); let impls: Vec<_> = impls .iter() @@ -1932,14 +1934,15 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { debug!("EncodeContext::encode_traits_and_impls()"); empty_proc_macro!(self); let tcx = self.tcx; - let mut all_impls: Vec<_> = tcx.crate_inherent_impls(()).incoherent_impls.iter().collect(); - tcx.with_stable_hashing_context(|mut ctx| { - all_impls.sort_by_cached_key(|&(&simp, _)| { - let mut hasher = StableHasher::new(); - simp.hash_stable(&mut ctx, &mut hasher); - hasher.finish::() - }) - }); + let all_impls: Vec<_> = tcx.crate_inherent_impls(()).incoherent_impls.iter().collect(); + // SORT-TEST + // tcx.with_stable_hashing_context(|mut ctx| { + // all_impls.sort_by_cached_key(|&(&simp, _)| { + // let mut hasher = StableHasher::new(); + // simp.hash_stable(&mut ctx, &mut hasher); + // hasher.finish::() + // }) + // }); let all_impls: Vec<_> = all_impls .into_iter() .map(|(&simp, impls)| { diff --git a/compiler/rustc_typeck/src/coherence/inherent_impls.rs b/compiler/rustc_typeck/src/coherence/inherent_impls.rs index cf1eb5e6fc9c7..af42d500cba40 100644 --- a/compiler/rustc_typeck/src/coherence/inherent_impls.rs +++ b/compiler/rustc_typeck/src/coherence/inherent_impls.rs @@ -7,6 +7,7 @@ //! `tcx.inherent_impls(def_id)`). That value, however, //! is computed by selecting an idea from this table. +//use hir::ItemId; //use hir::def_id::LOCAL_CRATE; //use hir::ItemId; use rustc_errors::struct_span_err; @@ -20,9 +21,13 @@ use rustc_span::Span; /// On-demand query: yields a map containing all types mapped to their inherent impls. pub fn crate_inherent_impls(tcx: TyCtxt<'_>, (): ()) -> CrateInherentImpls { let mut collect = InherentCollect { tcx, impls_map: Default::default() }; - //for (id, _) in tcx.impls_in_crate(LOCAL_CRATE).values().flatten() { - // collect.check_item(ItemId { def_id: id.to_owned().expect_local() }); - //} + // for cnum in tcx.crates(()) { + // for (id, _) in tcx.impls_in_crate(*cnum).values().flatten() { + // if id.is_local() { + // collect.check_item(ItemId { def_id: id.to_owned().expect_local() }); + // } + // } + // } for id in tcx.hir().items() { collect.check_item(id); } diff --git a/compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs index 9250ba3fe423e..68591efcf32f0 100644 --- a/compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs +++ b/compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs @@ -1,5 +1,4 @@ -use hir::def_id::LOCAL_CRATE; -use hir::ItemId; +//use hir::ItemId; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::struct_span_err; use rustc_hir as hir; @@ -15,8 +14,14 @@ use std::collections::hash_map::Entry; pub fn crate_inherent_impls_overlap_check(tcx: TyCtxt<'_>, (): ()) { let mut inherent_overlap_checker = InherentOverlapChecker { tcx }; - //for (id, _) in tcx.impls_in_crate(LOCAL_CRATE).values().flatten() { - // inherent_overlap_checker.check_item(ItemId { def_id: id.to_owned().expect_local() }); + + //for cnum in tcx.crates(()) { + // for (id, _) in tcx.impls_in_crate(*cnum).values().flatten() { + // if id.is_local() { + // inherent_overlap_checker + // .check_item(ItemId { def_id: id.to_owned().expect_local() }); + // } + // } //} for id in tcx.hir().items() { inherent_overlap_checker.check_item(id); From 11b2ade3afb1c2aae2f82dbcee2fbdcd9062540c Mon Sep 17 00:00:00 2001 From: Robert Cunningham Date: Fri, 13 Jan 2023 04:14:14 -0500 Subject: [PATCH 13/25] make compile after merge --- compiler/rustc_metadata/src/rmeta/encoder.rs | 12 ++++++------ compiler/rustc_middle/src/arena.rs | 2 +- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 429b78e9ebc26..63fe4f2184b05 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -4,8 +4,8 @@ use crate::rmeta::table::TableBuilder; use crate::rmeta::*; use rustc_ast::Attribute; -use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; +// use rustc_data_structures::fingerprint::Fingerprint; +use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet}; use rustc_data_structures::memmap::{Mmap, MmapMut}; use rustc_data_structures::stable_hasher::StableHasher; use rustc_data_structures::sync::{join, par_iter, Lrc, ParallelIterator}; @@ -1895,7 +1895,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { //let tcx = self.tcx; let fx_hash_map = self.tcx.impls_in_crate(LOCAL_CRATE).to_owned(); /* - TODO(robert): this is the new way to compute impls_in_crate; is it the same as what we had before? + todo: this is the new way to compute impls_in_crate; is it the same as what we had before? let tcx = self.tcx; let mut fx_hash_map: FxHashMap)>> = FxHashMap::default(); @@ -2317,8 +2317,8 @@ pub fn provide(providers: &mut Providers) { FxIndexMap::default(); for id in tcx.hir().items() { - if matches!(tcx.def_kind(id.def_id), DefKind::Impl) { - if let Some(trait_ref) = tcx.impl_trait_ref(id.def_id.to_def_id()) { + if matches!(tcx.def_kind(id.owner_id), DefKind::Impl) { + if let Some(trait_ref) = tcx.impl_trait_ref(id.owner_id.to_def_id()) { let simplified_self_ty = fast_reject::simplify_type( tcx, trait_ref.self_ty(), @@ -2328,7 +2328,7 @@ pub fn provide(providers: &mut Providers) { fx_hash_map .entry(trait_ref.def_id) .or_default() - .push((id.def_id.to_def_id(), simplified_self_ty)); + .push((id.owner_id.to_def_id(), simplified_self_ty)); } } } diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index aed5da5bcb7c8..91416a7d45ad9 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -80,7 +80,7 @@ macro_rules! arena_types { rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::Ty<'tcx>> >, [] all_traits: Vec, - [] trait_to_impl_and_ty: rustc_data_structures::fx::FxIndexMap>)>>, + [] trait_to_impl_and_ty: rustc_data_structures::fx::FxIndexMap)>>, [] trait_to_impl: rustc_data_structures::fx::FxIndexMap>, [] effective_visibilities: rustc_middle::middle::privacy::EffectiveVisibilities, [] foreign_module: rustc_session::cstore::ForeignModule, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index c6b8a5025082d..0d1c04f2be9b9 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1810,7 +1810,7 @@ rustc_queries! { } /// A list of all traits in a crate mapped to their impls in that crate. - query impls_in_crate(_: CrateNum) -> &'tcx FxIndexMap>)>> { + query impls_in_crate(_: CrateNum) -> &'tcx FxIndexMap)>> { eval_always desc { "fetching trait to impl map in a crate" } separate_provide_extern diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 54c0d5cd7cc3e..feae7bdac91aa 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -33,8 +33,8 @@ use rustc_ast as ast; use rustc_ast::node_id::NodeMap; use rustc_attr as attr; use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; -use rustc_data_structures::intern::{Interned, WithStableHash}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; +use rustc_data_structures::intern::Interned; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::tagged_ptr::CopyTaggedPtr; use rustc_hir as hir; From 3b486b2255a7344bdf0153baf310605dc3d6046c Mon Sep 17 00:00:00 2001 From: Robert Cunningham Date: Fri, 13 Jan 2023 07:02:32 -0500 Subject: [PATCH 14/25] fix git rename misses --- .../src/coherence/inherent_impls.rs | 9 + .../src/coherence/inherent_impls_overlap.rs | 10 + .../src/coherence/inherent_impls.rs | 254 -------------- .../src/coherence/inherent_impls_overlap.rs | 317 ------------------ 4 files changed, 19 insertions(+), 571 deletions(-) delete mode 100644 compiler/rustc_typeck/src/coherence/inherent_impls.rs delete mode 100644 compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index 6469f389bf91b..3dbb5c70228a1 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -19,6 +19,15 @@ use rustc_span::Span; /// On-demand query: yields a map containing all types mapped to their inherent impls. pub fn crate_inherent_impls(tcx: TyCtxt<'_>, (): ()) -> CrateInherentImpls { let mut collect = InherentCollect { tcx, impls_map: Default::default() }; + + // for cnum in tcx.crates(()) { + // for (id, _) in tcx.impls_in_crate(*cnum).values().flatten() { + // if id.is_local() { + // collect.check_item(ItemId { def_id: id.to_owned().expect_local() }); + // } + // } + // } + for id in tcx.hir().items() { collect.check_item(id); } diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs index a9331af4eab32..df934b11ab1a2 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs @@ -13,6 +13,16 @@ use std::collections::hash_map::Entry; pub fn crate_inherent_impls_overlap_check(tcx: TyCtxt<'_>, (): ()) { let mut inherent_overlap_checker = InherentOverlapChecker { tcx }; + + //for cnum in tcx.crates(()) { + // for (id, _) in tcx.impls_in_crate(*cnum).values().flatten() { + // if id.is_local() { + // inherent_overlap_checker + // .check_item(ItemId { def_id: id.to_owned().expect_local() }); + // } + // } + //} + for id in tcx.hir().items() { inherent_overlap_checker.check_item(id); } diff --git a/compiler/rustc_typeck/src/coherence/inherent_impls.rs b/compiler/rustc_typeck/src/coherence/inherent_impls.rs deleted file mode 100644 index af42d500cba40..0000000000000 --- a/compiler/rustc_typeck/src/coherence/inherent_impls.rs +++ /dev/null @@ -1,254 +0,0 @@ -//! The code in this module gathers up all of the inherent impls in -//! the current crate and organizes them in a map. It winds up -//! touching the whole crate and thus must be recomputed completely -//! for any change, but it is very cheap to compute. In practice, most -//! code in the compiler never *directly* requests this map. Instead, -//! it requests the inherent impls specific to some type (via -//! `tcx.inherent_impls(def_id)`). That value, however, -//! is computed by selecting an idea from this table. - -//use hir::ItemId; -//use hir::def_id::LOCAL_CRATE; -//use hir::ItemId; -use rustc_errors::struct_span_err; -use rustc_hir as hir; -use rustc_hir::def_id::{CrateNum, DefId, LocalDefId}; -use rustc_middle::ty::fast_reject::{simplify_type, SimplifiedType, TreatParams}; -use rustc_middle::ty::{self, CrateInherentImpls, Ty, TyCtxt}; -use rustc_span::symbol::sym; -use rustc_span::Span; - -/// On-demand query: yields a map containing all types mapped to their inherent impls. -pub fn crate_inherent_impls(tcx: TyCtxt<'_>, (): ()) -> CrateInherentImpls { - let mut collect = InherentCollect { tcx, impls_map: Default::default() }; - // for cnum in tcx.crates(()) { - // for (id, _) in tcx.impls_in_crate(*cnum).values().flatten() { - // if id.is_local() { - // collect.check_item(ItemId { def_id: id.to_owned().expect_local() }); - // } - // } - // } - for id in tcx.hir().items() { - collect.check_item(id); - } - collect.impls_map -} - -pub fn crate_incoherent_impls(tcx: TyCtxt<'_>, (_, simp): (CrateNum, SimplifiedType)) -> &[DefId] { - let crate_map = tcx.crate_inherent_impls(()); - tcx.arena.alloc_from_iter( - crate_map.incoherent_impls.get(&simp).unwrap_or(&Vec::new()).iter().map(|d| d.to_def_id()), - ) -} - -/// On-demand query: yields a vector of the inherent impls for a specific type. -pub fn inherent_impls(tcx: TyCtxt<'_>, ty_def_id: DefId) -> &[DefId] { - let ty_def_id = ty_def_id.expect_local(); - - let crate_map = tcx.crate_inherent_impls(()); - match crate_map.inherent_impls.get(&ty_def_id) { - Some(v) => &v[..], - None => &[], - } -} - -struct InherentCollect<'tcx> { - tcx: TyCtxt<'tcx>, - impls_map: CrateInherentImpls, -} - -const INTO_CORE: &str = "consider moving this inherent impl into `core` if possible"; -const INTO_DEFINING_CRATE: &str = - "consider moving this inherent impl into the crate defining the type if possible"; -const ADD_ATTR_TO_TY: &str = "alternatively add `#[rustc_has_incoherent_inherent_impls]` to the type \ - and `#[rustc_allow_incoherent_impl]` to the relevant impl items"; -const ADD_ATTR: &str = - "alternatively add `#[rustc_allow_incoherent_impl]` to the relevant impl items"; - -impl<'tcx> InherentCollect<'tcx> { - fn check_def_id(&mut self, item: &hir::Item<'_>, self_ty: Ty<'tcx>, def_id: DefId) { - let impl_def_id = item.def_id; - if let Some(def_id) = def_id.as_local() { - // Add the implementation to the mapping from implementation to base - // type def ID, if there is a base type for this implementation and - // the implementation does not have any associated traits. - let vec = self.impls_map.inherent_impls.entry(def_id).or_default(); - vec.push(impl_def_id.to_def_id()); - return; - } - - if self.tcx.features().rustc_attrs { - let hir::ItemKind::Impl(&hir::Impl { items, .. }) = item.kind else { - bug!("expected `impl` item: {:?}", item); - }; - - if !self.tcx.has_attr(def_id, sym::rustc_has_incoherent_inherent_impls) { - struct_span_err!( - self.tcx.sess, - item.span, - E0390, - "cannot define inherent `impl` for a type outside of the crate where the type is defined", - ) - .help(INTO_DEFINING_CRATE) - .span_help(item.span, ADD_ATTR_TO_TY) - .emit(); - return; - } - - for impl_item in items { - if !self - .tcx - .has_attr(impl_item.id.def_id.to_def_id(), sym::rustc_allow_incoherent_impl) - { - struct_span_err!( - self.tcx.sess, - item.span, - E0390, - "cannot define inherent `impl` for a type outside of the crate where the type is defined", - ) - .help(INTO_DEFINING_CRATE) - .span_help(impl_item.span, ADD_ATTR) - .emit(); - return; - } - } - - if let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::AsInfer) { - self.impls_map.incoherent_impls.entry(simp).or_default().push(impl_def_id); - } else { - bug!("unexpected self type: {:?}", self_ty); - } - } else { - struct_span_err!( - self.tcx.sess, - item.span, - E0116, - "cannot define inherent `impl` for a type outside of the crate \ - where the type is defined" - ) - .span_label(item.span, "impl for type defined outside of crate.") - .note("define and implement a trait or new type instead") - .emit(); - } - } - - fn check_primitive_impl( - &mut self, - impl_def_id: LocalDefId, - ty: Ty<'tcx>, - items: &[hir::ImplItemRef], - span: Span, - ) { - if !self.tcx.hir().rustc_coherence_is_core() { - if self.tcx.features().rustc_attrs { - for item in items { - if !self - .tcx - .has_attr(item.id.def_id.to_def_id(), sym::rustc_allow_incoherent_impl) - { - struct_span_err!( - self.tcx.sess, - span, - E0390, - "cannot define inherent `impl` for primitive types outside of `core`", - ) - .help(INTO_CORE) - .span_help(item.span, ADD_ATTR) - .emit(); - return; - } - } - } else { - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0390, - "cannot define inherent `impl` for primitive types", - ); - err.help("consider using an extension trait instead"); - if let ty::Ref(_, subty, _) = ty.kind() { - err.note(&format!( - "you could also try moving the reference to \ - uses of `{}` (such as `self`) within the implementation", - subty - )); - } - err.emit(); - return; - } - } - - if let Some(simp) = simplify_type(self.tcx, ty, TreatParams::AsInfer) { - self.impls_map.incoherent_impls.entry(simp).or_default().push(impl_def_id); - } else { - bug!("unexpected primitive type: {:?}", ty); - } - } - - fn check_item(&mut self, id: hir::ItemId) { - let item = self.tcx.hir().item(id); - let hir::ItemKind::Impl(hir::Impl { of_trait: None, self_ty: ty, ref items, .. }) = item.kind else { - return; - }; - - let self_ty = self.tcx.type_of(item.def_id); - match *self_ty.kind() { - ty::Adt(def, _) => { - self.check_def_id(item, self_ty, def.did()); - } - ty::Foreign(did) => { - self.check_def_id(item, self_ty, did); - } - ty::Dynamic(data, ..) if data.principal_def_id().is_some() => { - self.check_def_id(item, self_ty, data.principal_def_id().unwrap()); - } - ty::Dynamic(..) => { - struct_span_err!( - self.tcx.sess, - ty.span, - E0785, - "cannot define inherent `impl` for a dyn auto trait" - ) - .span_label(ty.span, "impl requires at least one non-auto trait") - .note("define and implement a new trait or type instead") - .emit(); - } - ty::Bool - | ty::Char - | ty::Int(_) - | ty::Uint(_) - | ty::Float(_) - | ty::Str - | ty::Array(..) - | ty::Slice(_) - | ty::RawPtr(_) - | ty::Ref(..) - | ty::Never - | ty::FnPtr(_) - | ty::Tuple(..) => self.check_primitive_impl(item.def_id, self_ty, items, ty.span), - ty::Projection(..) | ty::Opaque(..) | ty::Param(_) => { - let mut err = struct_span_err!( - self.tcx.sess, - ty.span, - E0118, - "no nominal type found for inherent implementation" - ); - - err.span_label(ty.span, "impl requires a nominal type") - .note("either implement a trait on it or create a newtype to wrap it instead"); - - err.emit(); - } - ty::FnDef(..) - | ty::Closure(..) - | ty::Generator(..) - | ty::GeneratorWitness(..) - | ty::Bound(..) - | ty::Placeholder(_) - | ty::Infer(_) => { - bug!("unexpected impl self type of impl: {:?} {:?}", item.def_id, self_ty); - } - ty::Error(_) => {} - } - } -} diff --git a/compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs deleted file mode 100644 index 68591efcf32f0..0000000000000 --- a/compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs +++ /dev/null @@ -1,317 +0,0 @@ -//use hir::ItemId; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_errors::struct_span_err; -use rustc_hir as hir; -use rustc_hir::def::DefKind; -use rustc_hir::def_id::DefId; -use rustc_index::vec::IndexVec; -use rustc_middle::traits::specialization_graph::OverlapMode; -use rustc_middle::ty::{self, TyCtxt}; -use rustc_span::Symbol; -use rustc_trait_selection::traits::{self, SkipLeakCheck}; -use smallvec::SmallVec; -use std::collections::hash_map::Entry; - -pub fn crate_inherent_impls_overlap_check(tcx: TyCtxt<'_>, (): ()) { - let mut inherent_overlap_checker = InherentOverlapChecker { tcx }; - - //for cnum in tcx.crates(()) { - // for (id, _) in tcx.impls_in_crate(*cnum).values().flatten() { - // if id.is_local() { - // inherent_overlap_checker - // .check_item(ItemId { def_id: id.to_owned().expect_local() }); - // } - // } - //} - for id in tcx.hir().items() { - inherent_overlap_checker.check_item(id); - } -} - -struct InherentOverlapChecker<'tcx> { - tcx: TyCtxt<'tcx>, -} - -impl<'tcx> InherentOverlapChecker<'tcx> { - /// Checks whether any associated items in impls 1 and 2 share the same identifier and - /// namespace. - fn impls_have_common_items( - &self, - impl_items1: &ty::AssocItems<'_>, - impl_items2: &ty::AssocItems<'_>, - ) -> bool { - let mut impl_items1 = &impl_items1; - let mut impl_items2 = &impl_items2; - - // Performance optimization: iterate over the smaller list - if impl_items1.len() > impl_items2.len() { - std::mem::swap(&mut impl_items1, &mut impl_items2); - } - - for item1 in impl_items1.in_definition_order() { - let collision = impl_items2 - .filter_by_name_unhygienic(item1.name) - .any(|item2| self.compare_hygienically(item1, item2)); - - if collision { - return true; - } - } - - false - } - - fn compare_hygienically(&self, item1: &ty::AssocItem, item2: &ty::AssocItem) -> bool { - // Symbols and namespace match, compare hygienically. - item1.kind.namespace() == item2.kind.namespace() - && item1.ident(self.tcx).normalize_to_macros_2_0() - == item2.ident(self.tcx).normalize_to_macros_2_0() - } - - fn check_for_common_items_in_impls( - &self, - impl1: DefId, - impl2: DefId, - overlap: traits::OverlapResult<'_>, - ) { - let impl_items1 = self.tcx.associated_items(impl1); - let impl_items2 = self.tcx.associated_items(impl2); - - for item1 in impl_items1.in_definition_order() { - let collision = impl_items2 - .filter_by_name_unhygienic(item1.name) - .find(|item2| self.compare_hygienically(item1, item2)); - - if let Some(item2) = collision { - let name = item1.ident(self.tcx).normalize_to_macros_2_0(); - let mut err = struct_span_err!( - self.tcx.sess, - self.tcx.def_span(item1.def_id), - E0592, - "duplicate definitions with name `{}`", - name - ); - err.span_label( - self.tcx.def_span(item1.def_id), - format!("duplicate definitions for `{}`", name), - ); - err.span_label( - self.tcx.def_span(item2.def_id), - format!("other definition for `{}`", name), - ); - - for cause in &overlap.intercrate_ambiguity_causes { - cause.add_intercrate_ambiguity_hint(&mut err); - } - - if overlap.involves_placeholder { - traits::add_placeholder_note(&mut err); - } - - err.emit(); - } - } - } - - fn check_for_overlapping_inherent_impls( - &self, - overlap_mode: OverlapMode, - impl1_def_id: DefId, - impl2_def_id: DefId, - ) { - traits::overlapping_impls( - self.tcx, - impl1_def_id, - impl2_def_id, - // We go ahead and just skip the leak check for - // inherent impls without warning. - SkipLeakCheck::Yes, - overlap_mode, - |overlap| { - self.check_for_common_items_in_impls(impl1_def_id, impl2_def_id, overlap); - false - }, - || true, - ); - } - - fn check_item(&mut self, id: hir::ItemId) { - let def_kind = self.tcx.def_kind(id.def_id); - if !matches!(def_kind, DefKind::Enum | DefKind::Struct | DefKind::Trait | DefKind::Union) { - return; - } - - let impls = self.tcx.inherent_impls(id.def_id); - - // If there is only one inherent impl block, - // there is nothing to overlap check it with - if impls.len() <= 1 { - return; - } - - let overlap_mode = OverlapMode::get(self.tcx, id.def_id.to_def_id()); - - let impls_items = impls - .iter() - .map(|impl_def_id| (impl_def_id, self.tcx.associated_items(*impl_def_id))) - .collect::>(); - - // Perform a O(n^2) algorithm for small n, - // otherwise switch to an allocating algorithm with - // faster asymptotic runtime. - const ALLOCATING_ALGO_THRESHOLD: usize = 500; - if impls.len() < ALLOCATING_ALGO_THRESHOLD { - for (i, &(&impl1_def_id, impl_items1)) in impls_items.iter().enumerate() { - for &(&impl2_def_id, impl_items2) in &impls_items[(i + 1)..] { - if self.impls_have_common_items(impl_items1, impl_items2) { - self.check_for_overlapping_inherent_impls( - overlap_mode, - impl1_def_id, - impl2_def_id, - ); - } - } - } - } else { - // Build a set of connected regions of impl blocks. - // Two impl blocks are regarded as connected if they share - // an item with the same unhygienic identifier. - // After we have assembled the connected regions, - // run the O(n^2) algorithm on each connected region. - // This is advantageous to running the algorithm over the - // entire graph when there are many connected regions. - - rustc_index::newtype_index! { - pub struct RegionId { - ENCODABLE = custom - } - } - struct ConnectedRegion { - idents: SmallVec<[Symbol; 8]>, - impl_blocks: FxHashSet, - } - let mut connected_regions: IndexVec = Default::default(); - // Reverse map from the Symbol to the connected region id. - let mut connected_region_ids = FxHashMap::default(); - - for (i, &(&_impl_def_id, impl_items)) in impls_items.iter().enumerate() { - if impl_items.len() == 0 { - continue; - } - // First obtain a list of existing connected region ids - let mut idents_to_add = SmallVec::<[Symbol; 8]>::new(); - let mut ids = impl_items - .in_definition_order() - .filter_map(|item| { - let entry = connected_region_ids.entry(item.name); - if let Entry::Occupied(e) = &entry { - Some(*e.get()) - } else { - idents_to_add.push(item.name); - None - } - }) - .collect::>(); - // Sort the id list so that the algorithm is deterministic - ids.sort_unstable(); - ids.dedup(); - let ids = ids; - match &ids[..] { - // Create a new connected region - [] => { - let id_to_set = connected_regions.next_index(); - // Update the connected region ids - for ident in &idents_to_add { - connected_region_ids.insert(*ident, id_to_set); - } - connected_regions.insert( - id_to_set, - ConnectedRegion { - idents: idents_to_add, - impl_blocks: std::iter::once(i).collect(), - }, - ); - } - // Take the only id inside the list - &[id_to_set] => { - let region = connected_regions[id_to_set].as_mut().unwrap(); - region.impl_blocks.insert(i); - region.idents.extend_from_slice(&idents_to_add); - // Update the connected region ids - for ident in &idents_to_add { - connected_region_ids.insert(*ident, id_to_set); - } - } - // We have multiple connected regions to merge. - // In the worst case this might add impl blocks - // one by one and can thus be O(n^2) in the size - // of the resulting final connected region, but - // this is no issue as the final step to check - // for overlaps runs in O(n^2) as well. - &[id_to_set, ..] => { - let mut region = connected_regions.remove(id_to_set).unwrap(); - region.impl_blocks.insert(i); - region.idents.extend_from_slice(&idents_to_add); - // Update the connected region ids - for ident in &idents_to_add { - connected_region_ids.insert(*ident, id_to_set); - } - - // Remove other regions from ids. - for &id in ids.iter() { - if id == id_to_set { - continue; - } - let r = connected_regions.remove(id).unwrap(); - for ident in r.idents.iter() { - connected_region_ids.insert(*ident, id_to_set); - } - region.idents.extend_from_slice(&r.idents); - region.impl_blocks.extend(r.impl_blocks); - } - - connected_regions.insert(id_to_set, region); - } - } - } - - debug!( - "churning through {} components (sum={}, avg={}, var={}, max={})", - connected_regions.len(), - impls.len(), - impls.len() / connected_regions.len(), - { - let avg = impls.len() / connected_regions.len(); - let s = connected_regions - .iter() - .flatten() - .map(|r| r.impl_blocks.len() as isize - avg as isize) - .map(|v| v.abs() as usize) - .sum::(); - s / connected_regions.len() - }, - connected_regions.iter().flatten().map(|r| r.impl_blocks.len()).max().unwrap() - ); - // List of connected regions is built. Now, run the overlap check - // for each pair of impl blocks in the same connected region. - for region in connected_regions.into_iter().flatten() { - let mut impl_blocks = - region.impl_blocks.into_iter().collect::>(); - impl_blocks.sort_unstable(); - for (i, &impl1_items_idx) in impl_blocks.iter().enumerate() { - let &(&impl1_def_id, impl_items1) = &impls_items[impl1_items_idx]; - for &impl2_items_idx in impl_blocks[(i + 1)..].iter() { - let &(&impl2_def_id, impl_items2) = &impls_items[impl2_items_idx]; - if self.impls_have_common_items(impl_items1, impl_items2) { - self.check_for_overlapping_inherent_impls( - overlap_mode, - impl1_def_id, - impl2_def_id, - ); - } - } - } - } - } - } -} From 621ba62b778b3be945a521a5e56310cdad1d667b Mon Sep 17 00:00:00 2001 From: Robert Cunningham Date: Sat, 14 Jan 2023 11:52:57 -0500 Subject: [PATCH 15/25] debug checks --- .../src/coherence/inherent_impls.rs | 14 ++++++++++ .../src/coherence/inherent_impls_overlap.rs | 28 +++++++++++++------ compiler/rustc_middle/src/query/mod.rs | 2 +- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index 3dbb5c70228a1..d41a8e736a461 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -7,6 +7,8 @@ //! `tcx.inherent_impls(def_id)`). That value, however, //! is computed by selecting an idea from this table. +use hir::def_id::LOCAL_CRATE; +use hir::{ItemId, OwnerId}; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::DefKind; @@ -28,7 +30,17 @@ pub fn crate_inherent_impls(tcx: TyCtxt<'_>, (): ()) -> CrateInherentImpls { // } // } + debug!("recent..."); + for (id, _) in tcx.impls_in_crate(LOCAL_CRATE).values().flatten() { + // collect.check_item(ItemId { owner_id: OwnerId { def_id: id.expect_local() } }); + debug!( + "adjusted: would have checked {:?}", + ItemId { owner_id: OwnerId { def_id: id.expect_local() } } + ) + } + for id in tcx.hir().items() { + debug!("old code checking {:?}", id); collect.check_item(id); } collect.impls_map @@ -190,6 +202,8 @@ impl<'tcx> InherentCollect<'tcx> { return; } + debug!("not rejected"); + let item = self.tcx.hir().item(id); let hir::ItemKind::Impl(hir::Impl { of_trait: None, self_ty: ty, ref items, .. }) = item.kind else { return; diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs index df934b11ab1a2..af44ef1e6944b 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs @@ -1,3 +1,5 @@ +use hir::def_id::LOCAL_CRATE; +//use hir::{ItemId, OwnerId}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::struct_span_err; use rustc_hir as hir; @@ -14,16 +16,25 @@ use std::collections::hash_map::Entry; pub fn crate_inherent_impls_overlap_check(tcx: TyCtxt<'_>, (): ()) { let mut inherent_overlap_checker = InherentOverlapChecker { tcx }; - //for cnum in tcx.crates(()) { - // for (id, _) in tcx.impls_in_crate(*cnum).values().flatten() { - // if id.is_local() { - // inherent_overlap_checker - // .check_item(ItemId { def_id: id.to_owned().expect_local() }); - // } - // } - //} + // for cnum in tcx.crates(()) { + // for (id, _) in tcx.impls_in_crate(*cnum).values().flatten() { + // debug!("new loop {:?}; local: {:?}", id, id.is_local()); + // if id.is_local() { + // // DefId -> hir::ItemId + // //inherent_overlap_checker + // // .check_item(ItemId { owner_id: OwnerId { def_id: id.expect_local() } }); + // } + // } + // } + + for (id, _) in tcx.impls_in_crate(LOCAL_CRATE).values().flatten() { + debug!("adjusted: would have checked {:?}", id); + // inherent_overlap_checker + // .check_item(ItemId { owner_id: OwnerId { def_id: id.expect_local() } }); + } for id in tcx.hir().items() { + debug!("old code actually checking: {:?}", id); inherent_overlap_checker.check_item(id); } } @@ -170,6 +181,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> { if !matches!(def_kind, DefKind::Enum | DefKind::Struct | DefKind::Trait | DefKind::Union) { return; } + debug!("not rejected"); let impls = self.tcx.inherent_impls(id.owner_id); diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 0d1c04f2be9b9..601fb853c2f83 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1809,7 +1809,7 @@ rustc_queries! { separate_provide_extern } - /// A list of all traits in a crate mapped to their impls in that crate. + /// A list of all traits in a crate mapped to their impls in that crate. Also includes None => inherent impls. query impls_in_crate(_: CrateNum) -> &'tcx FxIndexMap)>> { eval_always desc { "fetching trait to impl map in a crate" } From bd356837ecafba1cc8a8c362f146a7e30786e3c9 Mon Sep 17 00:00:00 2001 From: Robert Cunningham Date: Sat, 14 Jan 2023 23:09:10 -0500 Subject: [PATCH 16/25] change type to option --- .../rustc_metadata/src/rmeta/decoder/cstore_impl.rs | 2 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 11 +++++++---- compiler/rustc_middle/src/arena.rs | 2 +- compiler/rustc_middle/src/query/mod.rs | 2 +- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 21cfc22bf6a23..7bb658785e965 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -289,7 +289,7 @@ provide! { tcx, def_id, other, cdata, extra_filename => { cdata.root.extra_filename.clone() } traits_in_crate => { tcx.arena.alloc_from_iter(cdata.get_traits()) } - impls_in_crate => { tcx.arena.alloc(cdata.get_trait_impl_map()) } + impls_in_crate => { tcx.arena.alloc(cdata.get_trait_impl_map().into_iter().map(|(key, value)| {(Some(key), value)}).collect()) } implementations_of_trait => { cdata.get_implementations_of_trait(tcx, other) } crate_incoherent_impls => { cdata.get_incoherent_impls(tcx, other) } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 63fe4f2184b05..acca52720084a 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1926,6 +1926,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let all_impls: Vec<_> = all_impls .into_iter() + .filter(|(trait_def_id, impls)| trait_def_id.is_some()) .map(|(trait_def_id, impls)| { // Bring everything into deterministic order for hashing // SORT-TEST @@ -1941,7 +1942,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { .collect(); TraitImpls { - trait_id: (trait_def_id.krate.as_u32(), trait_def_id.index), + trait_id: (trait_def_id.unwrap().krate.as_u32(), trait_def_id.unwrap().index), // todo robert, kind of ugly but works impls: self.lazy_array(&impls), } }) @@ -2294,7 +2295,7 @@ pub fn provide(providers: &mut Providers) { }) .collect(); - tcx.arena.alloc(o) + tcx.arena.alloc(o) // deal with this problem by removing all_local_trait_impls. }, traits_in_crate: |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); @@ -2313,7 +2314,7 @@ pub fn provide(providers: &mut Providers) { }, impls_in_crate: |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); - let mut fx_hash_map: FxIndexMap)>> = + let mut fx_hash_map: FxIndexMap, Vec<(DefId, Option)>> = FxIndexMap::default(); for id in tcx.hir().items() { @@ -2326,9 +2327,11 @@ pub fn provide(providers: &mut Providers) { ); fx_hash_map - .entry(trait_ref.def_id) + .entry(Some(trait_ref.def_id)) .or_default() .push((id.owner_id.to_def_id(), simplified_self_ty)); + } else { + fx_hash_map.entry(None).or_default().push((id.owner_id.to_def_id(), None)) } } } diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index 91416a7d45ad9..219e14ff956a3 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -80,7 +80,7 @@ macro_rules! arena_types { rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::Ty<'tcx>> >, [] all_traits: Vec, - [] trait_to_impl_and_ty: rustc_data_structures::fx::FxIndexMap)>>, + [] trait_to_impl_and_ty: rustc_data_structures::fx::FxIndexMap, Vec<(rustc_hir::def_id::DefId, Option)>>, [] trait_to_impl: rustc_data_structures::fx::FxIndexMap>, [] effective_visibilities: rustc_middle::middle::privacy::EffectiveVisibilities, [] foreign_module: rustc_session::cstore::ForeignModule, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 601fb853c2f83..d8867f16d999c 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1810,7 +1810,7 @@ rustc_queries! { } /// A list of all traits in a crate mapped to their impls in that crate. Also includes None => inherent impls. - query impls_in_crate(_: CrateNum) -> &'tcx FxIndexMap)>> { + query impls_in_crate(_: CrateNum) -> &'tcx FxIndexMap, Vec<(DefId, Option)>> { eval_always desc { "fetching trait to impl map in a crate" } separate_provide_extern From 58d15770b0194e6d4380dbf2191ec08874a0b7ec Mon Sep 17 00:00:00 2001 From: Robert Cunningham Date: Sat, 14 Jan 2023 23:52:29 -0500 Subject: [PATCH 17/25] remove local_impls_in_crate, find cycle --- .../src/coherence/builtin.rs | 2 +- .../src/coherence/inherent_impls.rs | 10 +-- .../src/coherence/inherent_impls_overlap.rs | 2 +- .../rustc_hir_analysis/src/coherence/mod.rs | 2 +- compiler/rustc_hir_analysis/src/lib.rs | 3 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 4 +- compiler/rustc_middle/src/hir/map/mod.rs | 7 ++- compiler/rustc_middle/src/query/mod.rs | 5 -- compiler/rustc_middle/src/ty/trait_def.rs | 2 +- src/tools/clippy/clippy_lints/src/derive.rs | 61 ++++++++++++------- 10 files changed, 59 insertions(+), 39 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 2e2c1591e9b44..15637c13d1ac9 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -38,7 +38,7 @@ impl<'tcx> Checker<'tcx> { F: FnMut(TyCtxt<'tcx>, LocalDefId), { if Some(self.trait_def_id) == trait_def_id { - for &impl_def_id in self.tcx.hir().trait_impls(self.trait_def_id) { + for impl_def_id in self.tcx.hir().trait_impls(self.trait_def_id) { f(self.tcx, impl_def_id); } } diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index d41a8e736a461..043abaca34ca6 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -32,17 +32,17 @@ pub fn crate_inherent_impls(tcx: TyCtxt<'_>, (): ()) -> CrateInherentImpls { debug!("recent..."); for (id, _) in tcx.impls_in_crate(LOCAL_CRATE).values().flatten() { - // collect.check_item(ItemId { owner_id: OwnerId { def_id: id.expect_local() } }); + collect.check_item(ItemId { owner_id: OwnerId { def_id: id.expect_local() } }); debug!( "adjusted: would have checked {:?}", ItemId { owner_id: OwnerId { def_id: id.expect_local() } } ) } - for id in tcx.hir().items() { - debug!("old code checking {:?}", id); - collect.check_item(id); - } + // for id in tcx.hir().items() { + // debug!("old code checking {:?}", id); + // collect.check_item(id); + // } collect.impls_map } diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs index af44ef1e6944b..42d0bf45e0477 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs @@ -1,5 +1,5 @@ use hir::def_id::LOCAL_CRATE; -//use hir::{ItemId, OwnerId}; +// use hir::{ItemId, OwnerId}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::struct_span_err; use rustc_hir as hir; diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index 1bf3768fead36..d9dc242585d2d 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -127,7 +127,7 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) { tcx.ensure().specialization_graph_of(def_id); let impls = tcx.hir().trait_impls(def_id); - for &impl_def_id in impls { + for impl_def_id in impls { let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap(); check_impl(tcx, impl_def_id, trait_ref); diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index ddc5b76688126..abb42db8221c8 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -98,6 +98,7 @@ mod outlives; pub mod structured_errors; mod variance; +use hir::def_id::LOCAL_CRATE; use rustc_errors::{struct_span_err, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def_id::DefId; @@ -502,7 +503,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> { tcx.sess.track_errors(|| { tcx.sess.time("coherence_checking", || { - for &trait_def_id in tcx.all_local_trait_impls(()).keys() { + for trait_def_id in tcx.impls_in_crate(LOCAL_CRATE).keys().filter_map(|x| *x) { tcx.ensure().coherent_trait(trait_def_id); } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index acca52720084a..d6aec7510a2b0 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1926,7 +1926,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let all_impls: Vec<_> = all_impls .into_iter() - .filter(|(trait_def_id, impls)| trait_def_id.is_some()) + .filter(|(trait_def_id, _)| trait_def_id.is_some()) .map(|(trait_def_id, impls)| { // Bring everything into deterministic order for hashing // SORT-TEST @@ -2283,6 +2283,7 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>, path: &Path) { pub fn provide(providers: &mut Providers) { *providers = Providers { + /* all_local_trait_impls: |tcx, _| { let o: FxIndexMap<_, _> = tcx .impls_in_crate(LOCAL_CRATE) @@ -2297,6 +2298,7 @@ pub fn provide(providers: &mut Providers) { tcx.arena.alloc(o) // deal with this problem by removing all_local_trait_impls. }, + */ traits_in_crate: |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 48bae7a2d4e1f..e34d9c655cf57 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -534,8 +534,11 @@ impl<'hir> Map<'hir> { } } - pub fn trait_impls(self, trait_did: DefId) -> &'hir [LocalDefId] { - self.tcx.all_local_trait_impls(()).get(&trait_did).map_or(&[], |xs| &xs[..]) + pub fn trait_impls(self, trait_did: DefId) -> Vec { + // changed from &'hir [LocalDefId] + self.tcx.impls_in_crate(LOCAL_CRATE).get(&Some(trait_did)).map_or(Vec::new(), |xs| { + xs.into_iter().map(|(id, _)| id.expect_local()).collect::>() + }) } /// Gets the attributes on the crate. This is preferable to diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index d8867f16d999c..f0b9fd0958a33 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1237,11 +1237,6 @@ rustc_queries! { desc { |tcx| "computing candidate for `{}`", key.1 } } - /// Return all `impl` blocks in the current crate. - query all_local_trait_impls(_: ()) -> &'tcx rustc_data_structures::fx::FxIndexMap> { - desc { "finding local trait impls" } - } - /// Given a trait `trait_id`, return all known `impl` blocks. query trait_impls_of(trait_id: DefId) -> ty::trait_def::TraitImpls { arena_cache diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index b38a5fbf20f5b..2ad2d74c6714b 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -235,7 +235,7 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait } } - for &impl_def_id in tcx.hir().trait_impls(trait_id) { + for impl_def_id in tcx.hir().trait_impls(trait_id) { let impl_def_id = impl_def_id.to_def_id(); let impl_self_ty = tcx.type_of(impl_def_id); diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index f4b15e0916dbf..54b63f3b56420 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -1,21 +1,24 @@ -use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then}; +use clippy_utils::diagnostics::{ + span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then, +}; use clippy_utils::paths; use clippy_utils::ty::{implements_trait, implements_trait_with_env, is_copy}; use clippy_utils::{is_lint_allowed, match_def_path}; +use hir::def_id::LOCAL_CRATE; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{walk_expr, walk_fn, walk_item, FnKind, Visitor}; use rustc_hir::{ - self as hir, BlockCheckMode, BodyId, Constness, Expr, ExprKind, FnDecl, HirId, Impl, Item, ItemKind, UnsafeSource, - Unsafety, + self as hir, BlockCheckMode, BodyId, Constness, Expr, ExprKind, FnDecl, HirId, Impl, Item, + ItemKind, UnsafeSource, Unsafety, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::nested_filter; use rustc_middle::traits::Reveal; use rustc_middle::ty::{ - self, Binder, BoundConstness, Clause, GenericArgKind, GenericParamDefKind, ImplPolarity, ParamEnv, PredicateKind, - TraitPredicate, Ty, TyCtxt, + self, Binder, BoundConstness, Clause, GenericArgKind, GenericParamDefKind, ImplPolarity, + ParamEnv, PredicateKind, TraitPredicate, Ty, TyCtxt, }; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; @@ -205,13 +208,10 @@ declare_lint_pass!(Derive => [ impl<'tcx> LateLintPass<'tcx> for Derive { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { - if let ItemKind::Impl(Impl { - of_trait: Some(ref trait_ref), - .. - }) = item.kind - { + if let ItemKind::Impl(Impl { of_trait: Some(ref trait_ref), .. }) = item.kind { let ty = cx.tcx.type_of(item.owner_id); - let is_automatically_derived = cx.tcx.has_attr(item.owner_id.to_def_id(), sym::automatically_derived); + let is_automatically_derived = + cx.tcx.has_attr(item.owner_id.to_def_id(), sym::automatically_derived); check_hash_peq(cx, item.span, trait_ref, ty, is_automatically_derived); check_ord_partial_ord(cx, item.span, trait_ref, ty, is_automatically_derived); @@ -328,7 +328,12 @@ fn check_ord_partial_ord<'tcx>( } /// Implementation of the `EXPL_IMPL_CLONE_ON_COPY` lint. -fn check_copy_clone<'tcx>(cx: &LateContext<'tcx>, item: &Item<'_>, trait_ref: &hir::TraitRef<'_>, ty: Ty<'tcx>) { +fn check_copy_clone<'tcx>( + cx: &LateContext<'tcx>, + item: &Item<'_>, + trait_ref: &hir::TraitRef<'_>, + ty: Ty<'tcx>, +) { let clone_id = match cx.tcx.lang_items().clone_trait() { Some(id) if trait_ref.trait_def_id() == Some(id) => id, _ => return, @@ -343,10 +348,10 @@ fn check_copy_clone<'tcx>(cx: &LateContext<'tcx>, item: &Item<'_>, trait_ref: &h // there's a Copy impl for any instance of the adt. if !is_copy(cx, ty) { if ty_subs.non_erasable_generics().next().is_some() { - let has_copy_impl = cx.tcx.all_local_trait_impls(()).get(©_id).map_or(false, |impls| { + let has_copy_impl = cx.tcx.impls_in_crate(LOCAL_CRATE).get(&Some(copy_id)).map_or(false, |impls| { impls .iter() - .any(|&id| matches!(cx.tcx.type_of(id).kind(), ty::Adt(adt, _) if ty_adt.did() == adt.did())) + .any(|(id, _)| matches!(cx.tcx.type_of(id).kind(), ty::Adt(adt, _) if ty_adt.did() == adt.did())) }); if !has_copy_impl { return; @@ -425,7 +430,14 @@ struct UnsafeVisitor<'a, 'tcx> { impl<'tcx> Visitor<'tcx> for UnsafeVisitor<'_, 'tcx> { type NestedFilter = nested_filter::All; - fn visit_fn(&mut self, kind: FnKind<'tcx>, decl: &'tcx FnDecl<'_>, body_id: BodyId, _: Span, id: HirId) { + fn visit_fn( + &mut self, + kind: FnKind<'tcx>, + decl: &'tcx FnDecl<'_>, + body_id: BodyId, + _: Span, + id: HirId, + ) { if self.has_unsafe { return; } @@ -461,7 +473,12 @@ impl<'tcx> Visitor<'tcx> for UnsafeVisitor<'_, 'tcx> { } /// Implementation of the `DERIVE_PARTIAL_EQ_WITHOUT_EQ` lint. -fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_ref: &hir::TraitRef<'_>, ty: Ty<'tcx>) { +fn check_partial_eq_without_eq<'tcx>( + cx: &LateContext<'tcx>, + span: Span, + trait_ref: &hir::TraitRef<'_>, + ty: Ty<'tcx>, +) { if_chain! { if let ty::Adt(adt, substs) = ty.kind(); if cx.tcx.visibility(adt.did()).is_public(); @@ -515,11 +532,13 @@ fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) -> ParamEnv::new( tcx.mk_predicates(ty_predicates.iter().map(|&(p, _)| p).chain( params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| { - tcx.mk_predicate(Binder::dummy(PredicateKind::Clause(Clause::Trait(TraitPredicate { - trait_ref: tcx.mk_trait_ref(eq_trait_id, [tcx.mk_param_from_def(param)]), - constness: BoundConstness::NotConst, - polarity: ImplPolarity::Positive, - })))) + tcx.mk_predicate(Binder::dummy(PredicateKind::Clause(Clause::Trait( + TraitPredicate { + trait_ref: tcx.mk_trait_ref(eq_trait_id, [tcx.mk_param_from_def(param)]), + constness: BoundConstness::NotConst, + polarity: ImplPolarity::Positive, + }, + )))) }), )), Reveal::UserFacing, From 90e12e833a4759a76a5a1ab1e70294cf686287b0 Mon Sep 17 00:00:00 2001 From: Robert Cunningham Date: Sun, 15 Jan 2023 00:39:49 -0500 Subject: [PATCH 18/25] passing tests --- .../src/coherence/inherent_impls.rs | 10 +++++----- compiler/rustc_hir_analysis/src/lib.rs | 1 + compiler/rustc_metadata/src/rmeta/encoder.rs | 14 ++++++++++++++ 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index 043abaca34ca6..d41a8e736a461 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -32,17 +32,17 @@ pub fn crate_inherent_impls(tcx: TyCtxt<'_>, (): ()) -> CrateInherentImpls { debug!("recent..."); for (id, _) in tcx.impls_in_crate(LOCAL_CRATE).values().flatten() { - collect.check_item(ItemId { owner_id: OwnerId { def_id: id.expect_local() } }); + // collect.check_item(ItemId { owner_id: OwnerId { def_id: id.expect_local() } }); debug!( "adjusted: would have checked {:?}", ItemId { owner_id: OwnerId { def_id: id.expect_local() } } ) } - // for id in tcx.hir().items() { - // debug!("old code checking {:?}", id); - // collect.check_item(id); - // } + for id in tcx.hir().items() { + debug!("old code checking {:?}", id); + collect.check_item(id); + } collect.impls_map } diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index abb42db8221c8..8c82c0955da2d 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -504,6 +504,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> { tcx.sess.track_errors(|| { tcx.sess.time("coherence_checking", || { for trait_def_id in tcx.impls_in_crate(LOCAL_CRATE).keys().filter_map(|x| *x) { + // todo, why doesn't this work with traits_in_crate? tcx.ensure().coherent_trait(trait_def_id); } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index d6aec7510a2b0..6b6288f58a8c4 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -2314,6 +2314,20 @@ pub fn provide(providers: &mut Providers) { tcx.arena.alloc_slice(&traits) }, + /* + impls_in_crate_list: |tcx, cnum| { + assert_eq!(cnum, LOCAL_CRATE); + + let mut impls = Vec::new(); + for id in tcx.hir().items() { + if matches!(tcx.def_kind(id.owner_id), DefKind::Impl) { + impls.push(id.owner_id.to_def_id()) + } + } + + tcx.arena.alloc_slice(&impls) + }, + */ impls_in_crate: |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); let mut fx_hash_map: FxIndexMap, Vec<(DefId, Option)>> = From 065543930fcfb8318121ef27753ac21afcfd7bc9 Mon Sep 17 00:00:00 2001 From: Robert Cunningham Date: Mon, 16 Jan 2023 07:22:39 -0500 Subject: [PATCH 19/25] revert everything --- .../src/coherence/builtin.rs | 2 +- .../src/coherence/inherent_impls.rs | 23 ---- .../src/coherence/inherent_impls_overlap.rs | 22 ---- .../rustc_hir_analysis/src/coherence/mod.rs | 2 +- compiler/rustc_hir_analysis/src/lib.rs | 4 +- compiler/rustc_metadata/src/rmeta/decoder.rs | 22 +--- .../src/rmeta/decoder/cstore_impl.rs | 1 - compiler/rustc_metadata/src/rmeta/encoder.rs | 112 ++++-------------- compiler/rustc_middle/src/arena.rs | 2 - compiler/rustc_middle/src/hir/map/mod.rs | 7 +- compiler/rustc_middle/src/hir/mod.rs | 1 + compiler/rustc_middle/src/query/mod.rs | 12 +- compiler/rustc_middle/src/ty/mod.rs | 3 +- compiler/rustc_middle/src/ty/trait_def.rs | 2 +- compiler/rustc_resolve/src/late.rs | 8 -- compiler/rustc_resolve/src/lib.rs | 4 + src/tools/clippy/clippy_lints/src/derive.rs | 61 ++++------ 17 files changed, 60 insertions(+), 228 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 15637c13d1ac9..2e2c1591e9b44 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -38,7 +38,7 @@ impl<'tcx> Checker<'tcx> { F: FnMut(TyCtxt<'tcx>, LocalDefId), { if Some(self.trait_def_id) == trait_def_id { - for impl_def_id in self.tcx.hir().trait_impls(self.trait_def_id) { + for &impl_def_id in self.tcx.hir().trait_impls(self.trait_def_id) { f(self.tcx, impl_def_id); } } diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index d41a8e736a461..6469f389bf91b 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -7,8 +7,6 @@ //! `tcx.inherent_impls(def_id)`). That value, however, //! is computed by selecting an idea from this table. -use hir::def_id::LOCAL_CRATE; -use hir::{ItemId, OwnerId}; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::DefKind; @@ -21,26 +19,7 @@ use rustc_span::Span; /// On-demand query: yields a map containing all types mapped to their inherent impls. pub fn crate_inherent_impls(tcx: TyCtxt<'_>, (): ()) -> CrateInherentImpls { let mut collect = InherentCollect { tcx, impls_map: Default::default() }; - - // for cnum in tcx.crates(()) { - // for (id, _) in tcx.impls_in_crate(*cnum).values().flatten() { - // if id.is_local() { - // collect.check_item(ItemId { def_id: id.to_owned().expect_local() }); - // } - // } - // } - - debug!("recent..."); - for (id, _) in tcx.impls_in_crate(LOCAL_CRATE).values().flatten() { - // collect.check_item(ItemId { owner_id: OwnerId { def_id: id.expect_local() } }); - debug!( - "adjusted: would have checked {:?}", - ItemId { owner_id: OwnerId { def_id: id.expect_local() } } - ) - } - for id in tcx.hir().items() { - debug!("old code checking {:?}", id); collect.check_item(id); } collect.impls_map @@ -202,8 +181,6 @@ impl<'tcx> InherentCollect<'tcx> { return; } - debug!("not rejected"); - let item = self.tcx.hir().item(id); let hir::ItemKind::Impl(hir::Impl { of_trait: None, self_ty: ty, ref items, .. }) = item.kind else { return; diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs index 42d0bf45e0477..a9331af4eab32 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs @@ -1,5 +1,3 @@ -use hir::def_id::LOCAL_CRATE; -// use hir::{ItemId, OwnerId}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::struct_span_err; use rustc_hir as hir; @@ -15,26 +13,7 @@ use std::collections::hash_map::Entry; pub fn crate_inherent_impls_overlap_check(tcx: TyCtxt<'_>, (): ()) { let mut inherent_overlap_checker = InherentOverlapChecker { tcx }; - - // for cnum in tcx.crates(()) { - // for (id, _) in tcx.impls_in_crate(*cnum).values().flatten() { - // debug!("new loop {:?}; local: {:?}", id, id.is_local()); - // if id.is_local() { - // // DefId -> hir::ItemId - // //inherent_overlap_checker - // // .check_item(ItemId { owner_id: OwnerId { def_id: id.expect_local() } }); - // } - // } - // } - - for (id, _) in tcx.impls_in_crate(LOCAL_CRATE).values().flatten() { - debug!("adjusted: would have checked {:?}", id); - // inherent_overlap_checker - // .check_item(ItemId { owner_id: OwnerId { def_id: id.expect_local() } }); - } - for id in tcx.hir().items() { - debug!("old code actually checking: {:?}", id); inherent_overlap_checker.check_item(id); } } @@ -181,7 +160,6 @@ impl<'tcx> InherentOverlapChecker<'tcx> { if !matches!(def_kind, DefKind::Enum | DefKind::Struct | DefKind::Trait | DefKind::Union) { return; } - debug!("not rejected"); let impls = self.tcx.inherent_impls(id.owner_id); diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index d9dc242585d2d..1bf3768fead36 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -127,7 +127,7 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) { tcx.ensure().specialization_graph_of(def_id); let impls = tcx.hir().trait_impls(def_id); - for impl_def_id in impls { + for &impl_def_id in impls { let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap(); check_impl(tcx, impl_def_id, trait_ref); diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 8c82c0955da2d..ddc5b76688126 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -98,7 +98,6 @@ mod outlives; pub mod structured_errors; mod variance; -use hir::def_id::LOCAL_CRATE; use rustc_errors::{struct_span_err, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def_id::DefId; @@ -503,8 +502,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> { tcx.sess.track_errors(|| { tcx.sess.time("coherence_checking", || { - for trait_def_id in tcx.impls_in_crate(LOCAL_CRATE).keys().filter_map(|x| *x) { - // todo, why doesn't this work with traits_in_crate? + for &trait_def_id in tcx.all_local_trait_impls(()).keys() { tcx.ensure().coherent_trait(trait_def_id); } diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 8b23e6f146e8e..143d8f2f1e18d 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -5,7 +5,7 @@ use crate::rmeta::*; use rustc_ast as ast; use rustc_data_structures::captures::Captures; -use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::{Lock, LockGuard, Lrc, OnceCell}; use rustc_data_structures::unhash::UnhashMap; @@ -1198,26 +1198,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { }) } - /// Decodes a map from trait to impls. - fn get_trait_impl_map(self) -> FxIndexMap)>> { - self.cdata - .trait_impls - .iter() - .map(|(&(trait_cnum_raw, trait_index), impls)| { - let krate = self.cnum_map[CrateNum::from_u32(trait_cnum_raw)]; - let trait_def_id = DefId { krate, index: trait_index }; - - return ( - trait_def_id, - impls - .decode(self) - .map(|(impl_index, ty)| (DefId { krate, index: impl_index }, ty)) - .collect(), - ); - }) - .collect() - } - fn get_all_incoherent_impls(self) -> impl Iterator + 'a { self.cdata .incoherent_impls diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 7bb658785e965..cb451931dfe17 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -289,7 +289,6 @@ provide! { tcx, def_id, other, cdata, extra_filename => { cdata.root.extra_filename.clone() } traits_in_crate => { tcx.arena.alloc_from_iter(cdata.get_traits()) } - impls_in_crate => { tcx.arena.alloc(cdata.get_trait_impl_map().into_iter().map(|(key, value)| {(Some(key), value)}).collect()) } implementations_of_trait => { cdata.get_implementations_of_trait(tcx, other) } crate_incoherent_impls => { cdata.get_incoherent_impls(tcx, other) } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 6b6288f58a8c4..030328d1e26ff 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -4,10 +4,10 @@ use crate::rmeta::table::TableBuilder; use crate::rmeta::*; use rustc_ast::Attribute; -// use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet}; +use rustc_data_structures::fingerprint::Fingerprint; +use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_data_structures::memmap::{Mmap, MmapMut}; -use rustc_data_structures::stable_hasher::StableHasher; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{join, par_iter, Lrc, ParallelIterator}; use rustc_data_structures::temp_dir::MaybeTempDir; use rustc_hir as hir; @@ -1892,10 +1892,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_impls(&mut self) -> LazyArray { debug!("EncodeContext::encode_traits_and_impls()"); empty_proc_macro!(self); - //let tcx = self.tcx; - let fx_hash_map = self.tcx.impls_in_crate(LOCAL_CRATE).to_owned(); - /* - todo: this is the new way to compute impls_in_crate; is it the same as what we had before? let tcx = self.tcx; let mut fx_hash_map: FxHashMap)>> = FxHashMap::default(); @@ -1916,33 +1912,22 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } } } - */ - let all_impls: Vec<_> = fx_hash_map.into_iter().collect(); + let mut all_impls: Vec<_> = fx_hash_map.into_iter().collect(); // Bring everything into deterministic order for hashing - // SORT-TEST - //all_impls.sort_by_cached_key(|&(trait_def_id, _)| tcx.def_path_hash(trait_def_id)); + all_impls.sort_by_cached_key(|&(trait_def_id, _)| tcx.def_path_hash(trait_def_id)); let all_impls: Vec<_> = all_impls .into_iter() - .filter(|(trait_def_id, _)| trait_def_id.is_some()) - .map(|(trait_def_id, impls)| { + .map(|(trait_def_id, mut impls)| { // Bring everything into deterministic order for hashing - // SORT-TEST - //impls.sort_by_cached_key(|&(index, _)| { - // tcx.hir().def_path_hash(LocalDefId { - // local_def_index: index.expect_local().local_def_index, - // }) - //}); - - let impls: Vec<_> = impls - .iter() - .map(|(def_id, ty)| (def_id.expect_local().local_def_index, *ty)) - .collect(); + impls.sort_by_cached_key(|&(index, _)| { + tcx.hir().def_path_hash(LocalDefId { local_def_index: index }) + }); TraitImpls { - trait_id: (trait_def_id.unwrap().krate.as_u32(), trait_def_id.unwrap().index), // todo robert, kind of ugly but works + trait_id: (trait_def_id.krate.as_u32(), trait_def_id.index), impls: self.lazy_array(&impls), } }) @@ -1955,15 +1940,14 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { debug!("EncodeContext::encode_traits_and_impls()"); empty_proc_macro!(self); let tcx = self.tcx; - let all_impls: Vec<_> = tcx.crate_inherent_impls(()).incoherent_impls.iter().collect(); - // SORT-TEST - // tcx.with_stable_hashing_context(|mut ctx| { - // all_impls.sort_by_cached_key(|&(&simp, _)| { - // let mut hasher = StableHasher::new(); - // simp.hash_stable(&mut ctx, &mut hasher); - // hasher.finish::() - // }) - // }); + let mut all_impls: Vec<_> = tcx.crate_inherent_impls(()).incoherent_impls.iter().collect(); + tcx.with_stable_hashing_context(|mut ctx| { + all_impls.sort_by_cached_key(|&(&simp, _)| { + let mut hasher = StableHasher::new(); + simp.hash_stable(&mut ctx, &mut hasher); + hasher.finish::() + }) + }); let all_impls: Vec<_> = all_impls .into_iter() .map(|(&simp, impls)| { @@ -2283,22 +2267,6 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>, path: &Path) { pub fn provide(providers: &mut Providers) { *providers = Providers { - /* - all_local_trait_impls: |tcx, _| { - let o: FxIndexMap<_, _> = tcx - .impls_in_crate(LOCAL_CRATE) - .iter() - .map(|(trait_id, impls)| { - ( - *trait_id, - impls.iter().map(|(id, _)| id.expect_local()).collect::>(), - ) - }) - .collect(); - - tcx.arena.alloc(o) // deal with this problem by removing all_local_trait_impls. - }, - */ traits_in_crate: |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); @@ -2309,51 +2277,11 @@ pub fn provide(providers: &mut Providers) { } } - // We don't need to sort, since the default order is source-code order. - // The source code is hashed into crate_hash, so if crate_hash is stable then it must be stable too. - + // Bring everything into deterministic order. + traits.sort_by_cached_key(|&def_id| tcx.def_path_hash(def_id)); tcx.arena.alloc_slice(&traits) }, - /* - impls_in_crate_list: |tcx, cnum| { - assert_eq!(cnum, LOCAL_CRATE); - let mut impls = Vec::new(); - for id in tcx.hir().items() { - if matches!(tcx.def_kind(id.owner_id), DefKind::Impl) { - impls.push(id.owner_id.to_def_id()) - } - } - - tcx.arena.alloc_slice(&impls) - }, - */ - impls_in_crate: |tcx, cnum| { - assert_eq!(cnum, LOCAL_CRATE); - let mut fx_hash_map: FxIndexMap, Vec<(DefId, Option)>> = - FxIndexMap::default(); - - for id in tcx.hir().items() { - if matches!(tcx.def_kind(id.owner_id), DefKind::Impl) { - if let Some(trait_ref) = tcx.impl_trait_ref(id.owner_id.to_def_id()) { - let simplified_self_ty = fast_reject::simplify_type( - tcx, - trait_ref.self_ty(), - TreatParams::AsInfer, - ); - - fx_hash_map - .entry(Some(trait_ref.def_id)) - .or_default() - .push((id.owner_id.to_def_id(), simplified_self_ty)); - } else { - fx_hash_map.entry(None).or_default().push((id.owner_id.to_def_id(), None)) - } - } - } - - tcx.arena.alloc(fx_hash_map) - }, ..*providers } } diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index 219e14ff956a3..75282f958b53b 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -80,8 +80,6 @@ macro_rules! arena_types { rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::Ty<'tcx>> >, [] all_traits: Vec, - [] trait_to_impl_and_ty: rustc_data_structures::fx::FxIndexMap, Vec<(rustc_hir::def_id::DefId, Option)>>, - [] trait_to_impl: rustc_data_structures::fx::FxIndexMap>, [] effective_visibilities: rustc_middle::middle::privacy::EffectiveVisibilities, [] foreign_module: rustc_session::cstore::ForeignModule, [] foreign_modules: Vec, diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index e34d9c655cf57..48bae7a2d4e1f 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -534,11 +534,8 @@ impl<'hir> Map<'hir> { } } - pub fn trait_impls(self, trait_did: DefId) -> Vec { - // changed from &'hir [LocalDefId] - self.tcx.impls_in_crate(LOCAL_CRATE).get(&Some(trait_did)).map_or(Vec::new(), |xs| { - xs.into_iter().map(|(id, _)| id.expect_local()).collect::>() - }) + pub fn trait_impls(self, trait_did: DefId) -> &'hir [LocalDefId] { + self.tcx.all_local_trait_impls(()).get(&trait_did).map_or(&[], |xs| &xs[..]) } /// Gets the attributes on the crate. This is preferable to diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 3fc44b16eb45c..a633201e3d9ae 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -172,6 +172,7 @@ pub fn provide(providers: &mut Providers) { } }; providers.opt_def_kind = |tcx, def_id| tcx.hir().opt_def_kind(def_id.expect_local()); + providers.all_local_trait_impls = |tcx, ()| &tcx.resolutions(()).trait_impls; providers.expn_that_defined = |tcx, id| { let id = id.expect_local(); tcx.resolutions(()).expn_that_defined.get(&id).copied().unwrap_or(ExpnId::root()) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index f0b9fd0958a33..076ce1bdb3486 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1237,6 +1237,11 @@ rustc_queries! { desc { |tcx| "computing candidate for `{}`", key.1 } } + /// Return all `impl` blocks in the current crate. + query all_local_trait_impls(_: ()) -> &'tcx rustc_data_structures::fx::FxIndexMap> { + desc { "finding local trait impls" } + } + /// Given a trait `trait_id`, return all known `impl` blocks. query trait_impls_of(trait_id: DefId) -> ty::trait_def::TraitImpls { arena_cache @@ -1804,13 +1809,6 @@ rustc_queries! { separate_provide_extern } - /// A list of all traits in a crate mapped to their impls in that crate. Also includes None => inherent impls. - query impls_in_crate(_: CrateNum) -> &'tcx FxIndexMap, Vec<(DefId, Option)>> { - eval_always - desc { "fetching trait to impl map in a crate" } - separate_provide_extern - } - /// The list of symbols exported from the given crate. /// /// - All names contained in `exported_symbols(cnum)` are guaranteed to diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index feae7bdac91aa..993e95b351484 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -33,7 +33,7 @@ use rustc_ast as ast; use rustc_ast::node_id::NodeMap; use rustc_attr as attr; use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::intern::Interned; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::tagged_ptr::CopyTaggedPtr; @@ -175,6 +175,7 @@ pub struct ResolverGlobalCtxt { /// via `extern crate` item and not `--extern` option or compiler built-in. pub extern_prelude: FxHashMap, pub main_def: Option, + pub trait_impls: FxIndexMap>, /// A list of proc macro LocalDefIds, written out in the order in which /// they are declared in the static array generated by proc_macro_harness. pub proc_macros: Vec, diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index 2ad2d74c6714b..b38a5fbf20f5b 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -235,7 +235,7 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait } } - for impl_def_id in tcx.hir().trait_impls(trait_id) { + for &impl_def_id in tcx.hir().trait_impls(trait_id) { let impl_def_id = impl_def_id.to_def_id(); let impl_self_ty = tcx.type_of(impl_def_id); diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 9001c71987ef9..ca43762aa214e 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2661,13 +2661,6 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { opt_trait_reference.as_ref(), self_type, |this, trait_id| { - let item_def_id = this.r.local_def_id(item_id).to_def_id(); - let res = Res::SelfTyAlias { - alias_to: item_def_id, - forbid_generic: false, - is_trait_impl: trait_id.is_some() - }; - /* let item_def_id = this.r.local_def_id(item_id); // Register the trait definitions from here. @@ -2685,7 +2678,6 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { forbid_generic: false, is_trait_impl: trait_id.is_some() }; - */ this.with_self_rib(res, |this| { if let Some(trait_ref) = opt_trait_reference.as_ref() { // Resolve type arguments in the trait path. diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 3376b4ad2c260..84d9794ccf266 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1035,6 +1035,7 @@ pub struct Resolver<'a> { item_generics_num_lifetimes: FxHashMap, main_def: Option, + trait_impls: FxIndexMap>, /// A list of proc macro LocalDefIds, written out in the order in which /// they are declared in the static array generated by proc_macro_harness. proc_macros: Vec, @@ -1362,6 +1363,7 @@ impl<'a> Resolver<'a> { legacy_const_generic_args: Default::default(), item_generics_num_lifetimes: Default::default(), main_def: Default::default(), + trait_impls: Default::default(), proc_macros: Default::default(), confused_type_with_std_module: Default::default(), lifetime_elision_allowed: Default::default(), @@ -1438,6 +1440,7 @@ impl<'a> Resolver<'a> { .map(|(ident, entry)| (ident.name, entry.introduced_by_item)) .collect(), main_def, + trait_impls: self.trait_impls, proc_macros, confused_type_with_std_module, registered_tools: self.registered_tools, @@ -1480,6 +1483,7 @@ impl<'a> Resolver<'a> { .map(|(ident, entry)| (ident.name, entry.introduced_by_item)) .collect(), main_def: self.main_def, + trait_impls: self.trait_impls.clone(), proc_macros, confused_type_with_std_module: self.confused_type_with_std_module.clone(), registered_tools: self.registered_tools.clone(), diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index 54b63f3b56420..f4b15e0916dbf 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -1,24 +1,21 @@ -use clippy_utils::diagnostics::{ - span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then, -}; +use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then}; use clippy_utils::paths; use clippy_utils::ty::{implements_trait, implements_trait_with_env, is_copy}; use clippy_utils::{is_lint_allowed, match_def_path}; -use hir::def_id::LOCAL_CRATE; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{walk_expr, walk_fn, walk_item, FnKind, Visitor}; use rustc_hir::{ - self as hir, BlockCheckMode, BodyId, Constness, Expr, ExprKind, FnDecl, HirId, Impl, Item, - ItemKind, UnsafeSource, Unsafety, + self as hir, BlockCheckMode, BodyId, Constness, Expr, ExprKind, FnDecl, HirId, Impl, Item, ItemKind, UnsafeSource, + Unsafety, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::nested_filter; use rustc_middle::traits::Reveal; use rustc_middle::ty::{ - self, Binder, BoundConstness, Clause, GenericArgKind, GenericParamDefKind, ImplPolarity, - ParamEnv, PredicateKind, TraitPredicate, Ty, TyCtxt, + self, Binder, BoundConstness, Clause, GenericArgKind, GenericParamDefKind, ImplPolarity, ParamEnv, PredicateKind, + TraitPredicate, Ty, TyCtxt, }; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; @@ -208,10 +205,13 @@ declare_lint_pass!(Derive => [ impl<'tcx> LateLintPass<'tcx> for Derive { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { - if let ItemKind::Impl(Impl { of_trait: Some(ref trait_ref), .. }) = item.kind { + if let ItemKind::Impl(Impl { + of_trait: Some(ref trait_ref), + .. + }) = item.kind + { let ty = cx.tcx.type_of(item.owner_id); - let is_automatically_derived = - cx.tcx.has_attr(item.owner_id.to_def_id(), sym::automatically_derived); + let is_automatically_derived = cx.tcx.has_attr(item.owner_id.to_def_id(), sym::automatically_derived); check_hash_peq(cx, item.span, trait_ref, ty, is_automatically_derived); check_ord_partial_ord(cx, item.span, trait_ref, ty, is_automatically_derived); @@ -328,12 +328,7 @@ fn check_ord_partial_ord<'tcx>( } /// Implementation of the `EXPL_IMPL_CLONE_ON_COPY` lint. -fn check_copy_clone<'tcx>( - cx: &LateContext<'tcx>, - item: &Item<'_>, - trait_ref: &hir::TraitRef<'_>, - ty: Ty<'tcx>, -) { +fn check_copy_clone<'tcx>(cx: &LateContext<'tcx>, item: &Item<'_>, trait_ref: &hir::TraitRef<'_>, ty: Ty<'tcx>) { let clone_id = match cx.tcx.lang_items().clone_trait() { Some(id) if trait_ref.trait_def_id() == Some(id) => id, _ => return, @@ -348,10 +343,10 @@ fn check_copy_clone<'tcx>( // there's a Copy impl for any instance of the adt. if !is_copy(cx, ty) { if ty_subs.non_erasable_generics().next().is_some() { - let has_copy_impl = cx.tcx.impls_in_crate(LOCAL_CRATE).get(&Some(copy_id)).map_or(false, |impls| { + let has_copy_impl = cx.tcx.all_local_trait_impls(()).get(©_id).map_or(false, |impls| { impls .iter() - .any(|(id, _)| matches!(cx.tcx.type_of(id).kind(), ty::Adt(adt, _) if ty_adt.did() == adt.did())) + .any(|&id| matches!(cx.tcx.type_of(id).kind(), ty::Adt(adt, _) if ty_adt.did() == adt.did())) }); if !has_copy_impl { return; @@ -430,14 +425,7 @@ struct UnsafeVisitor<'a, 'tcx> { impl<'tcx> Visitor<'tcx> for UnsafeVisitor<'_, 'tcx> { type NestedFilter = nested_filter::All; - fn visit_fn( - &mut self, - kind: FnKind<'tcx>, - decl: &'tcx FnDecl<'_>, - body_id: BodyId, - _: Span, - id: HirId, - ) { + fn visit_fn(&mut self, kind: FnKind<'tcx>, decl: &'tcx FnDecl<'_>, body_id: BodyId, _: Span, id: HirId) { if self.has_unsafe { return; } @@ -473,12 +461,7 @@ impl<'tcx> Visitor<'tcx> for UnsafeVisitor<'_, 'tcx> { } /// Implementation of the `DERIVE_PARTIAL_EQ_WITHOUT_EQ` lint. -fn check_partial_eq_without_eq<'tcx>( - cx: &LateContext<'tcx>, - span: Span, - trait_ref: &hir::TraitRef<'_>, - ty: Ty<'tcx>, -) { +fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_ref: &hir::TraitRef<'_>, ty: Ty<'tcx>) { if_chain! { if let ty::Adt(adt, substs) = ty.kind(); if cx.tcx.visibility(adt.did()).is_public(); @@ -532,13 +515,11 @@ fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) -> ParamEnv::new( tcx.mk_predicates(ty_predicates.iter().map(|&(p, _)| p).chain( params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| { - tcx.mk_predicate(Binder::dummy(PredicateKind::Clause(Clause::Trait( - TraitPredicate { - trait_ref: tcx.mk_trait_ref(eq_trait_id, [tcx.mk_param_from_def(param)]), - constness: BoundConstness::NotConst, - polarity: ImplPolarity::Positive, - }, - )))) + tcx.mk_predicate(Binder::dummy(PredicateKind::Clause(Clause::Trait(TraitPredicate { + trait_ref: tcx.mk_trait_ref(eq_trait_id, [tcx.mk_param_from_def(param)]), + constness: BoundConstness::NotConst, + polarity: ImplPolarity::Positive, + })))) }), )), Reveal::UserFacing, From ecc2c080eeee29890304ab73e5203901891b02bd Mon Sep 17 00:00:00 2001 From: Robert Cunningham Date: Mon, 16 Jan 2023 07:55:46 -0500 Subject: [PATCH 20/25] clean and clarify --- .../src/coherence/inherent_impls.rs | 6 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 74 ++++++++----------- compiler/rustc_middle/src/query/mod.rs | 7 ++ 3 files changed, 41 insertions(+), 46 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index 6469f389bf91b..092fc8c8a73e7 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -7,6 +7,8 @@ //! `tcx.inherent_impls(def_id)`). That value, however, //! is computed by selecting an idea from this table. +use hir::def_id::LOCAL_CRATE; +use hir::{ItemId, OwnerId}; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::DefKind; @@ -19,8 +21,8 @@ use rustc_span::Span; /// On-demand query: yields a map containing all types mapped to their inherent impls. pub fn crate_inherent_impls(tcx: TyCtxt<'_>, (): ()) -> CrateInherentImpls { let mut collect = InherentCollect { tcx, impls_map: Default::default() }; - for id in tcx.hir().items() { - collect.check_item(id); + for id in tcx.impls_in_crate(LOCAL_CRATE) { + collect.check_item(ItemId { owner_id: OwnerId { def_id: id.expect_local() } }); } collect.impls_map } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 030328d1e26ff..5d268832b9720 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -4,10 +4,9 @@ use crate::rmeta::table::TableBuilder; use crate::rmeta::*; use rustc_ast::Attribute; -use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_data_structures::memmap::{Mmap, MmapMut}; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_data_structures::stable_hasher::StableHasher; use rustc_data_structures::sync::{join, par_iter, Lrc, ParallelIterator}; use rustc_data_structures::temp_dir::MaybeTempDir; use rustc_hir as hir; @@ -1896,40 +1895,25 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let mut fx_hash_map: FxHashMap)>> = FxHashMap::default(); - for id in tcx.hir().items() { - if matches!(tcx.def_kind(id.owner_id), DefKind::Impl) { - if let Some(trait_ref) = tcx.impl_trait_ref(id.owner_id) { - let simplified_self_ty = fast_reject::simplify_type( - self.tcx, - trait_ref.self_ty(), - TreatParams::AsInfer, - ); - - fx_hash_map - .entry(trait_ref.def_id) - .or_default() - .push((id.owner_id.def_id.local_def_index, simplified_self_ty)); - } + for id in tcx.impls_in_crate(LOCAL_CRATE) { + if let Some(trait_ref) = tcx.impl_trait_ref(id) { + let simplified_self_ty = + fast_reject::simplify_type(self.tcx, trait_ref.self_ty(), TreatParams::AsInfer); + + fx_hash_map + .entry(trait_ref.def_id) + .or_default() + .push((id.expect_local().local_def_index, simplified_self_ty)); } } - let mut all_impls: Vec<_> = fx_hash_map.into_iter().collect(); - - // Bring everything into deterministic order for hashing - all_impls.sort_by_cached_key(|&(trait_def_id, _)| tcx.def_path_hash(trait_def_id)); + let all_impls: Vec<_> = fx_hash_map.into_iter().collect(); let all_impls: Vec<_> = all_impls .into_iter() - .map(|(trait_def_id, mut impls)| { - // Bring everything into deterministic order for hashing - impls.sort_by_cached_key(|&(index, _)| { - tcx.hir().def_path_hash(LocalDefId { local_def_index: index }) - }); - - TraitImpls { - trait_id: (trait_def_id.krate.as_u32(), trait_def_id.index), - impls: self.lazy_array(&impls), - } + .map(|(trait_def_id, impls)| TraitImpls { + trait_id: (trait_def_id.krate.as_u32(), trait_def_id.index), + impls: self.lazy_array(&impls), }) .collect(); @@ -1940,22 +1924,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { debug!("EncodeContext::encode_traits_and_impls()"); empty_proc_macro!(self); let tcx = self.tcx; - let mut all_impls: Vec<_> = tcx.crate_inherent_impls(()).incoherent_impls.iter().collect(); - tcx.with_stable_hashing_context(|mut ctx| { - all_impls.sort_by_cached_key(|&(&simp, _)| { - let mut hasher = StableHasher::new(); - simp.hash_stable(&mut ctx, &mut hasher); - hasher.finish::() - }) - }); + let all_impls: Vec<_> = tcx.crate_inherent_impls(()).incoherent_impls.iter().collect(); let all_impls: Vec<_> = all_impls .into_iter() .map(|(&simp, impls)| { - let mut impls: Vec<_> = + let impls: Vec<_> = impls.into_iter().map(|def_id| def_id.local_def_index).collect(); - impls.sort_by_cached_key(|&local_def_index| { - tcx.hir().def_path_hash(LocalDefId { local_def_index }) - }); IncoherentImpls { self_ty: simp, impls: self.lazy_array(impls) } }) @@ -2277,10 +2251,22 @@ pub fn provide(providers: &mut Providers) { } } - // Bring everything into deterministic order. - traits.sort_by_cached_key(|&def_id| tcx.def_path_hash(def_id)); + // We don't need to sort, since the default order is source-code order. tcx.arena.alloc_slice(&traits) }, + impls_in_crate: |tcx, cnum| { + assert_eq!(cnum, LOCAL_CRATE); + + let mut impls = Vec::new(); + for id in tcx.hir().items() { + if matches!(tcx.def_kind(id.owner_id), DefKind::Impl) { + impls.push(id.owner_id.to_def_id()) + } + } + + // We don't need to sort, since the default order is source-code order. + tcx.arena.alloc_slice(&impls) + }, ..*providers } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 076ce1bdb3486..7d11175e1443b 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1809,6 +1809,13 @@ rustc_queries! { separate_provide_extern } + /// A list of all impls in a crate. + query impls_in_crate(_: CrateNum) -> &'tcx [DefId] { + eval_always + desc { "fetching trait to impl map in a crate" } + separate_provide_extern + } + /// The list of symbols exported from the given crate. /// /// - All names contained in `exported_symbols(cnum)` are guaranteed to From 66179b980f3333bc5d4bebb1125f4029449af9cf Mon Sep 17 00:00:00 2001 From: Robert Cunningham Date: Mon, 16 Jan 2023 10:29:51 -0500 Subject: [PATCH 21/25] passes tests --- .../src/coherence/inherent_impls.rs | 4 +-- compiler/rustc_passes/src/reachable.rs | 26 ++++++++++++++++++- .../clippy_lints/src/same_name_method.rs | 13 ++++++---- 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index 092fc8c8a73e7..370fdcad45997 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -179,9 +179,7 @@ impl<'tcx> InherentCollect<'tcx> { } fn check_item(&mut self, id: hir::ItemId) { - if !matches!(self.tcx.def_kind(id.owner_id), DefKind::Impl) { - return; - } + debug_assert!(matches!(self.tcx.def_kind(id.owner_id), DefKind::Impl)); let item = self.tcx.hir().item(id); let hir::ItemKind::Impl(hir::Impl { of_trait: None, self_ty: ty, ref items, .. }) = item.kind else { diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index ad09522038678..8d34c008a89af 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -5,6 +5,8 @@ // makes all other generics or inline functions that it references // reachable as well. +// use hir::def_id::LOCAL_CRATE; +// use hir::{ItemId, OwnerId}; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; @@ -325,6 +327,7 @@ fn check_item<'tcx>( } // We need only trait impls here, not inherent impls, and only non-exported ones + // todo can this be made more efficient let item = tcx.hir().item(id); if let hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref trait_ref), ref items, .. }) = item.kind @@ -406,9 +409,22 @@ fn reachable_set(tcx: TyCtxt<'_>, (): ()) -> FxHashSet { // trait items are used from inlinable code through method call syntax or UFCS, or their // trait is a lang item. let crate_items = tcx.hir_crate_items(()); + // let impl_items = crate_items.impl_items(); + // let my_impl_items = tcx.impls_in_crate(LOCAL_CRATE); + + // if impl_items.collect::>().len() != my_impl_items.len() { + // // todo remove + // panic!("Different length :'("); + // } for id in crate_items.items() { - check_item(tcx, id, &mut reachable_context.worklist, effective_visibilities); + check_item( + tcx, + // ItemId { owner_id: OwnerId { def_id: id.expect_local() } }, + id, + &mut reachable_context.worklist, + effective_visibilities, + ); } for id in crate_items.impl_items() { @@ -416,6 +432,14 @@ fn reachable_set(tcx: TyCtxt<'_>, (): ()) -> FxHashSet { reachable_context.worklist.push(id.owner_id.def_id); } } + + /* + for def_id in tcx.impls_in_crate(LOCAL_CRATE) { + if has_custom_linkage(tcx, def_id.expect_local()) { + reachable_context.worklist.push(def_id.expect_local()); + } + } + */ } // Step 2: Mark all symbols that the symbols on the worklist touch. diff --git a/src/tools/clippy/clippy_lints/src/same_name_method.rs b/src/tools/clippy/clippy_lints/src/same_name_method.rs index 17763128cd143..4c83063ca8678 100644 --- a/src/tools/clippy/clippy_lints/src/same_name_method.rs +++ b/src/tools/clippy/clippy_lints/src/same_name_method.rs @@ -1,7 +1,8 @@ use clippy_utils::diagnostics::span_lint_hir_and_then; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::{HirId, Impl, ItemKind, Node, Path, QPath, TraitRef, TyKind}; +use rustc_hir::def_id::LOCAL_CRATE; +use rustc_hir::{HirId, Impl, ItemId, ItemKind, Node, OwnerId, Path, QPath, TraitRef, TyKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::AssocKind; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -51,10 +52,12 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod { fn check_crate_post(&mut self, cx: &LateContext<'tcx>) { let mut map = FxHashMap::::default(); - for id in cx.tcx.hir().items() { - if matches!(cx.tcx.def_kind(id.owner_id), DefKind::Impl) - && let item = cx.tcx.hir().item(id) - && let ItemKind::Impl(Impl { + for id in cx.tcx.impls_in_crate(LOCAL_CRATE) { + let id = ItemId { owner_id: OwnerId { def_id: id.expect_local() } }; + // todo can I make this impls_in_crate? + debug_assert!(matches!(cx.tcx.def_kind(id.owner_id), DefKind::Impl)); + let item = cx.tcx.hir().item(id); + if let ItemKind::Impl(Impl { items, of_trait, self_ty, From a1bee1c5ca5e9e604661d69eadd13d9ac8bf896a Mon Sep 17 00:00:00 2001 From: Robert Cunningham Date: Tue, 17 Jan 2023 03:15:53 -0500 Subject: [PATCH 22/25] finish merge --- compiler/rustc_metadata/src/rmeta/encoder.rs | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index ae08a0afdfccb..d707403dab2de 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1895,18 +1895,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let mut fx_hash_map: FxHashMap)>> = FxHashMap::default(); - // for id in tcx.impls_in_crate(LOCAL_CRATE) { - // if let Some(trait_ref) = tcx.impl_trait_ref(id) { - // let simplified_self_ty = - // fast_reject::simplify_type(self.tcx, trait_ref.self_ty(), TreatParams::AsInfer); - - // fx_hash_map - // .entry(trait_ref.def_id) - // .or_default() - // .push((id.expect_local().local_def_index, simplified_self_ty)); - for id in tcx.impls_in_crate(LOCAL_CRATE) { - if let Some(trait_ref) = tcx.impl_trait_ref(id.owner_id) { + if let Some(trait_ref) = tcx.impl_trait_ref(id) { let trait_ref = trait_ref.subst_identity(); let simplified_self_ty = @@ -1915,7 +1905,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fx_hash_map .entry(trait_ref.def_id) .or_default() - .push((id.local_def_index, simplified_self_ty)); + .push((id.expect_local().local_def_index, simplified_self_ty)); } } From d313486bdf2845adc40c23a3742928a7a57e5dd8 Mon Sep 17 00:00:00 2001 From: Robert Cunningham Date: Tue, 17 Jan 2023 04:41:46 -0500 Subject: [PATCH 23/25] remove comment churn --- compiler/rustc_passes/src/reachable.rs | 25 +------------------ .../clippy_lints/src/same_name_method.rs | 1 - 2 files changed, 1 insertion(+), 25 deletions(-) diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index 8d34c008a89af..12ca7c244b38c 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -5,8 +5,6 @@ // makes all other generics or inline functions that it references // reachable as well. -// use hir::def_id::LOCAL_CRATE; -// use hir::{ItemId, OwnerId}; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; @@ -409,22 +407,9 @@ fn reachable_set(tcx: TyCtxt<'_>, (): ()) -> FxHashSet { // trait items are used from inlinable code through method call syntax or UFCS, or their // trait is a lang item. let crate_items = tcx.hir_crate_items(()); - // let impl_items = crate_items.impl_items(); - // let my_impl_items = tcx.impls_in_crate(LOCAL_CRATE); - - // if impl_items.collect::>().len() != my_impl_items.len() { - // // todo remove - // panic!("Different length :'("); - // } for id in crate_items.items() { - check_item( - tcx, - // ItemId { owner_id: OwnerId { def_id: id.expect_local() } }, - id, - &mut reachable_context.worklist, - effective_visibilities, - ); + check_item(tcx, id, &mut reachable_context.worklist, effective_visibilities); } for id in crate_items.impl_items() { @@ -432,14 +417,6 @@ fn reachable_set(tcx: TyCtxt<'_>, (): ()) -> FxHashSet { reachable_context.worklist.push(id.owner_id.def_id); } } - - /* - for def_id in tcx.impls_in_crate(LOCAL_CRATE) { - if has_custom_linkage(tcx, def_id.expect_local()) { - reachable_context.worklist.push(def_id.expect_local()); - } - } - */ } // Step 2: Mark all symbols that the symbols on the worklist touch. diff --git a/src/tools/clippy/clippy_lints/src/same_name_method.rs b/src/tools/clippy/clippy_lints/src/same_name_method.rs index 4c83063ca8678..1d04a9303a907 100644 --- a/src/tools/clippy/clippy_lints/src/same_name_method.rs +++ b/src/tools/clippy/clippy_lints/src/same_name_method.rs @@ -54,7 +54,6 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod { for id in cx.tcx.impls_in_crate(LOCAL_CRATE) { let id = ItemId { owner_id: OwnerId { def_id: id.expect_local() } }; - // todo can I make this impls_in_crate? debug_assert!(matches!(cx.tcx.def_kind(id.owner_id), DefKind::Impl)); let item = cx.tcx.hir().item(id); if let ItemKind::Impl(Impl { From 5c07123c91fc6330770c5d5e423d2b38ecfd8463 Mon Sep 17 00:00:00 2001 From: Robert Cunningham Date: Tue, 17 Jan 2023 04:42:50 -0500 Subject: [PATCH 24/25] remove last comment --- compiler/rustc_passes/src/reachable.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index 12ca7c244b38c..ad09522038678 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -325,7 +325,6 @@ fn check_item<'tcx>( } // We need only trait impls here, not inherent impls, and only non-exported ones - // todo can this be made more efficient let item = tcx.hir().item(id); if let hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref trait_ref), ref items, .. }) = item.kind From 37aba4537e22fec7fcf36eadd525c945f79eaa5c Mon Sep 17 00:00:00 2001 From: Robert Cunningham Date: Sat, 21 Jan 2023 01:08:34 -0500 Subject: [PATCH 25/25] add comment to address review --- src/tools/clippy/clippy_lints/src/same_name_method.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tools/clippy/clippy_lints/src/same_name_method.rs b/src/tools/clippy/clippy_lints/src/same_name_method.rs index 1d04a9303a907..dcf31a8751bfa 100644 --- a/src/tools/clippy/clippy_lints/src/same_name_method.rs +++ b/src/tools/clippy/clippy_lints/src/same_name_method.rs @@ -54,7 +54,10 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod { for id in cx.tcx.impls_in_crate(LOCAL_CRATE) { let id = ItemId { owner_id: OwnerId { def_id: id.expect_local() } }; + debug_assert!(matches!(cx.tcx.def_kind(id.owner_id), DefKind::Impl)); + // impls_in_crate returns only items with DefKind::Impl, so this will always be true. + let item = cx.tcx.hir().item(id); if let ItemKind::Impl(Impl { items,