diff options
Diffstat (limited to 'compiler/rustc_middle/src')
| -rw-r--r-- | compiler/rustc_middle/src/query/erase.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/query/mod.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/context.rs | 14 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/mod.rs | 24 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/parameterized.rs | 1 |
5 files changed, 33 insertions, 18 deletions
diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 7039749b1b7..5666a59e38e 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -177,8 +177,8 @@ impl EraseType for Option<mir::DestructuredConstant<'_>> { type Result = [u8; size_of::<Option<mir::DestructuredConstant<'static>>>()]; } -impl EraseType for Option<ty::EarlyBinder<ty::TraitRef<'_>>> { - type Result = [u8; size_of::<Option<ty::EarlyBinder<ty::TraitRef<'static>>>>()]; +impl EraseType for Option<ty::EarlyBinder<ty::ImplTraitHeader<'_>>> { + type Result = [u8; size_of::<Option<ty::EarlyBinder<ty::ImplTraitHeader<'static>>>>()]; } impl EraseType for Option<ty::EarlyBinder<Ty<'_>>> { diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 5a158edab72..60d195e4d3e 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -846,17 +846,13 @@ rustc_queries! { cache_on_disk_if { true } } - /// Given an `impl_id`, return the trait it implements. + /// Given an `impl_id`, return the trait it implements along with some header information. /// Return `None` if this is an inherent impl. - query impl_trait_ref(impl_id: DefId) -> Option<ty::EarlyBinder<ty::TraitRef<'tcx>>> { + query impl_trait_header(impl_id: DefId) -> Option<ty::EarlyBinder<ty::ImplTraitHeader<'tcx>>> { desc { |tcx| "computing trait implemented by `{}`", tcx.def_path_str(impl_id) } cache_on_disk_if { impl_id.is_local() } separate_provide_extern } - query impl_polarity(impl_id: DefId) -> ty::ImplPolarity { - desc { |tcx| "computing implementation polarity of `{}`", tcx.def_path_str(impl_id) } - separate_provide_extern - } query issue33140_self_ty(key: DefId) -> Option<ty::EarlyBinder<ty::Ty<'tcx>>> { desc { |tcx| "computing Self type wrt issue #33140 `{}`", tcx.def_path_str(key) } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 9a0eea6592f..bd86c1c284e 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2316,6 +2316,20 @@ impl<'tcx> TyCtxt<'tcx> { pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] { self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..]) } + + /// Given an `impl_id`, return the trait it implements. + /// Return `None` if this is an inherent impl. + pub fn impl_trait_ref( + self, + def_id: impl IntoQueryParam<DefId>, + ) -> Option<ty::EarlyBinder<ty::TraitRef<'tcx>>> { + Some(self.impl_trait_header(def_id)?.map_bound(|h| h.trait_ref)) + } + + pub fn impl_polarity(self, def_id: impl IntoQueryParam<DefId>) -> ty::ImplPolarity { + self.impl_trait_header(def_id) + .map_or(ty::ImplPolarity::Positive, |h| h.skip_binder().polarity) + } } /// Parameter attributes that can only be determined by examining the body of a function instead diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index af77ba02ad2..6ee74ef2fb6 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -248,6 +248,12 @@ pub struct ImplHeader<'tcx> { pub predicates: Vec<Predicate<'tcx>>, } +#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, TyEncodable, TyDecodable, HashStable)] +pub struct ImplTraitHeader<'tcx> { + pub trait_ref: ty::TraitRef<'tcx>, + pub polarity: ImplPolarity, +} + #[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable)] pub enum ImplSubject<'tcx> { Trait(TraitRef<'tcx>), @@ -1602,17 +1608,16 @@ impl<'tcx> TyCtxt<'tcx> { def_id1: DefId, def_id2: DefId, ) -> Option<ImplOverlapKind> { - let impl_trait_ref1 = self.impl_trait_ref(def_id1); - let impl_trait_ref2 = self.impl_trait_ref(def_id2); + let impl1 = self.impl_trait_header(def_id1).unwrap().instantiate_identity(); + let impl2 = self.impl_trait_header(def_id2).unwrap().instantiate_identity(); + // If either trait impl references an error, they're allowed to overlap, // as one of them essentially doesn't exist. - if impl_trait_ref1.is_some_and(|tr| tr.instantiate_identity().references_error()) - || impl_trait_ref2.is_some_and(|tr| tr.instantiate_identity().references_error()) - { + if impl1.references_error() || impl2.references_error() { return Some(ImplOverlapKind::Permitted { marker: false }); } - match (self.impl_polarity(def_id1), self.impl_polarity(def_id2)) { + match (impl1.polarity, impl2.polarity) { (ImplPolarity::Reservation, _) | (_, ImplPolarity::Reservation) => { // `#[rustc_reservation_impl]` impls don't overlap with anything return Some(ImplOverlapKind::Permitted { marker: false }); @@ -1627,10 +1632,9 @@ impl<'tcx> TyCtxt<'tcx> { }; let is_marker_overlap = { - let is_marker_impl = |trait_ref: Option<EarlyBinder<TraitRef<'_>>>| -> bool { - trait_ref.is_some_and(|tr| self.trait_def(tr.skip_binder().def_id).is_marker) - }; - is_marker_impl(impl_trait_ref1) && is_marker_impl(impl_trait_ref2) + let is_marker_impl = + |trait_ref: TraitRef<'_>| -> bool { self.trait_def(trait_ref.def_id).is_marker }; + is_marker_impl(impl1.trait_ref) && is_marker_impl(impl2.trait_ref) }; if is_marker_overlap { diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs index 47f9d9e61ad..045856dd9cd 100644 --- a/compiler/rustc_middle/src/ty/parameterized.rs +++ b/compiler/rustc_middle/src/ty/parameterized.rs @@ -134,4 +134,5 @@ parameterized_over_tcx! { ty::Predicate, ty::Clause, ty::ClauseKind, + ty::ImplTraitHeader } |
