diff options
| author | lcnr <rust@lcnr.de> | 2022-03-15 16:30:30 +0100 |
|---|---|---|
| committer | lcnr <rust@lcnr.de> | 2022-03-30 11:23:58 +0200 |
| commit | bef6f3e895beede5bfd5ba4bb12898615c156d59 (patch) | |
| tree | 724e0593725707bbff014409e6b495142830315b /compiler/rustc_middle | |
| parent | 4558a125b6108f3c080e88d7746e1d422b969bef (diff) | |
| download | rust-bef6f3e895beede5bfd5ba4bb12898615c156d59.tar.gz rust-bef6f3e895beede5bfd5ba4bb12898615c156d59.zip | |
rework implementation for inherent impls for builtin types
Diffstat (limited to 'compiler/rustc_middle')
| -rw-r--r-- | compiler/rustc_middle/src/hir/map/mod.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/query/mod.rs | 13 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/impls_ty.rs | 13 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/mod.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/trait_def.rs | 18 |
5 files changed, 51 insertions, 0 deletions
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index ec20e888333..8afa6e70e41 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -579,6 +579,10 @@ impl<'hir> Map<'hir> { self.attrs(CRATE_HIR_ID) } + pub fn rustc_coherence_is_core(self) -> bool { + self.krate_attrs().iter().any(|attr| attr.has_name(sym::rustc_coherence_is_core)) + } + pub fn get_module(self, module: LocalDefId) -> (&'hir Mod<'hir>, Span, HirId) { let hir_id = HirId::make_owner(module); match self.tcx.hir_owner(module).map(|o| o.node) { diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 95260e9e917..6d7e7ef0cb0 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -684,6 +684,10 @@ rustc_queries! { separate_provide_extern } + query incoherent_impls(key: SimplifiedType) -> &'tcx [DefId] { + desc { |tcx| "collecting all inherent impls for `{:?}`", key } + } + /// The result of unsafety-checking this `LocalDefId`. query unsafety_check_result(key: LocalDefId) -> &'tcx mir::UnsafetyCheckResult { desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key.to_def_id()) } @@ -1469,6 +1473,15 @@ rustc_queries! { separate_provide_extern } + /// Collects all incoherent impls for the given crate and type. + /// + /// Do not call this directly, but instead use the `incoherent_impls` query. + /// This query is only used to get the data necessary for that query. + query crate_incoherent_impls(key: (CrateNum, SimplifiedType)) -> &'tcx [DefId] { + desc { |tcx| "collecting all impls for a type in a crate" } + separate_provide_extern + } + query is_dllimport_foreign_item(def_id: DefId) -> bool { desc { |tcx| "is_dllimport_foreign_item({})", tcx.def_path_str(def_id) } } diff --git a/compiler/rustc_middle/src/ty/impls_ty.rs b/compiler/rustc_middle/src/ty/impls_ty.rs index 54a345daec8..2009364b24e 100644 --- a/compiler/rustc_middle/src/ty/impls_ty.rs +++ b/compiler/rustc_middle/src/ty/impls_ty.rs @@ -4,6 +4,7 @@ use crate::middle::region; use crate::mir; use crate::ty; +use crate::ty::fast_reject::SimplifiedType; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::HashingControls; @@ -55,6 +56,18 @@ where } } +impl<'a> ToStableHashKey<StableHashingContext<'a>> for SimplifiedType { + type KeyType = Fingerprint; + + #[inline] + fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> Fingerprint { + let mut hasher = StableHasher::new(); + let mut hcx: StableHashingContext<'a> = hcx.clone(); + self.hash_stable(&mut hcx, &mut hasher); + hasher.finish() + } +} + impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::subst::GenericArg<'tcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { self.unpack().hash_stable(hcx, hasher); diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 44c190e459c..dfc405b1195 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -25,6 +25,7 @@ use crate::middle::privacy::AccessLevels; use crate::mir::{Body, GeneratorLayout}; use crate::traits::{self, Reveal}; use crate::ty; +use crate::ty::fast_reject::SimplifiedType; use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef}; use crate::ty::util::Discr; use rustc_ast as ast; @@ -2335,6 +2336,7 @@ pub fn provide(providers: &mut ty::query::Providers) { super::middle::provide(providers); *providers = ty::query::Providers { trait_impls_of: trait_def::trait_impls_of_provider, + incoherent_impls: trait_def::incoherent_impls_provider, type_uninhabited_from: inhabitedness::type_uninhabited_from, const_param_default: consts::const_param_default, vtable_allocation: vtable::vtable_allocation_provider, @@ -2350,6 +2352,7 @@ pub fn provide(providers: &mut ty::query::Providers) { #[derive(Clone, Debug, Default, HashStable)] pub struct CrateInherentImpls { pub inherent_impls: LocalDefIdMap<Vec<DefId>>, + pub incoherent_impls: FxHashMap<SimplifiedType, Vec<LocalDefId>>, } #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, HashStable)] diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index 8ebeca50c41..943f610cc0d 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -2,9 +2,11 @@ use crate::traits::specialization_graph; use crate::ty::fast_reject::{self, SimplifiedType, TreatParams}; use crate::ty::fold::TypeFoldable; use crate::ty::{Ident, Ty, TyCtxt}; +use hir::def_id::LOCAL_CRATE; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::definitions::DefPathHash; +use std::iter; use rustc_data_structures::fx::FxIndexMap; use rustc_errors::ErrorGuaranteed; @@ -257,3 +259,19 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait impls } + +// Query provider for `incoherent_impls`. +#[instrument(level = "debug", skip(tcx))] +pub(super) fn incoherent_impls_provider(tcx: TyCtxt<'_>, simp: SimplifiedType) -> &[DefId] { + let mut impls = Vec::new(); + + for cnum in iter::once(LOCAL_CRATE).chain(tcx.crates(()).iter().copied()) { + for &impl_def_id in tcx.crate_incoherent_impls((cnum, simp)) { + impls.push(impl_def_id) + } + } + + debug!(?impls); + + tcx.arena.alloc_slice(&impls) +} |
