about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2024-02-10 21:26:48 +0000
committerOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2024-02-12 09:42:41 +0000
commit916951efcc51bb7c225a0dba676c34adef620f1d (patch)
tree3ae1d924d6928e84d89335b8e50c53b77036e8b9 /compiler
parentde4d615e6b86f7ef6deacd24610b0678230b8af3 (diff)
downloadrust-916951efcc51bb7c225a0dba676c34adef620f1d.tar.gz
rust-916951efcc51bb7c225a0dba676c34adef620f1d.zip
Make impl_trait_ref into a query also returning more information about the impl
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs51
-rw-r--r--compiler/rustc_incremental/src/persist/dirty_clean.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs5
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs2
-rw-r--r--compiler/rustc_middle/src/query/erase.rs5
-rw-r--r--compiler/rustc_middle/src/query/mod.rs4
-rw-r--r--compiler/rustc_middle/src/ty/context.rs9
8 files changed, 44 insertions, 36 deletions
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index f458ff01c10..0f0facdca65 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -78,7 +78,7 @@ pub fn provide(providers: &mut Providers) {
         trait_def,
         adt_def,
         fn_sig,
-        impl_trait_ref,
+        impl_trait_header,
         impl_polarity,
         coroutine_kind,
         coroutine_for_closure,
@@ -598,7 +598,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
         hir::ItemKind::Impl { .. } => {
             tcx.ensure().generics_of(def_id);
             tcx.ensure().type_of(def_id);
-            tcx.ensure().impl_trait_ref(def_id);
+            tcx.ensure().impl_trait_header(def_id);
             tcx.ensure().predicates_of(def_id);
         }
         hir::ItemKind::Trait(..) => {
@@ -1323,19 +1323,20 @@ fn suggest_impl_trait<'tcx>(
     None
 }
 
-fn impl_trait_ref(
+fn impl_trait_header(
     tcx: TyCtxt<'_>,
     def_id: LocalDefId,
-) -> Option<ty::EarlyBinder<ty::TraitRef<'_>>> {
+) -> Option<(ty::EarlyBinder<ty::TraitRef<'_>>, ty::ImplPolarity)> {
     let icx = ItemCtxt::new(tcx, def_id);
-    let impl_ = tcx.hir().expect_item(def_id).expect_impl();
+    let item = tcx.hir().expect_item(def_id);
+    let impl_ = item.expect_impl();
     impl_
         .of_trait
         .as_ref()
         .map(|ast_trait_ref| {
             let selfty = tcx.type_of(def_id).instantiate_identity();
 
-            if let Some(ErrorGuaranteed { .. }) = check_impl_constness(
+            let impl_trait_ref = if let Some(ErrorGuaranteed { .. }) = check_impl_constness(
                 tcx,
                 tcx.is_const_trait_impl_raw(def_id.to_def_id()),
                 ast_trait_ref,
@@ -1360,9 +1361,9 @@ fn impl_trait_ref(
                 icx.astconv().instantiate_mono_trait_ref(trait_ref, selfty)
             } else {
                 icx.astconv().instantiate_mono_trait_ref(ast_trait_ref, selfty)
-            }
+            };
+            (ty::EarlyBinder::bind(impl_trait_ref), polarity_of_impl(tcx, def_id,  impl_, item.span))
         })
-        .map(ty::EarlyBinder::bind)
 }
 
 fn check_impl_constness(
@@ -1391,42 +1392,38 @@ fn check_impl_constness(
 }
 
 fn impl_polarity(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::ImplPolarity {
-    let is_rustc_reservation = tcx.has_attr(def_id, sym::rustc_reservation_impl);
     let item = tcx.hir().expect_item(def_id);
-    match &item.kind {
-        hir::ItemKind::Impl(hir::Impl {
-            polarity: hir::ImplPolarity::Negative(span),
-            of_trait,
-            ..
-        }) => {
+    polarity_of_impl(tcx, def_id, item.expect_impl(), item.span)
+}
+
+fn polarity_of_impl(
+    tcx: TyCtxt<'_>,
+    def_id: LocalDefId,
+    impl_: &hir::Impl<'_>,
+    span: Span,
+) -> ty::ImplPolarity {
+    let is_rustc_reservation = tcx.has_attr(def_id, sym::rustc_reservation_impl);
+    match &impl_ {
+        hir::Impl { polarity: hir::ImplPolarity::Negative(span), of_trait, .. } => {
             if is_rustc_reservation {
                 let span = span.to(of_trait.as_ref().map_or(*span, |t| t.path.span));
                 tcx.dcx().span_err(span, "reservation impls can't be negative");
             }
             ty::ImplPolarity::Negative
         }
-        hir::ItemKind::Impl(hir::Impl {
-            polarity: hir::ImplPolarity::Positive,
-            of_trait: None,
-            ..
-        }) => {
+        hir::Impl { polarity: hir::ImplPolarity::Positive, of_trait: None, .. } => {
             if is_rustc_reservation {
-                tcx.dcx().span_err(item.span, "reservation impls can't be inherent");
+                tcx.dcx().span_err(span, "reservation impls can't be inherent");
             }
             ty::ImplPolarity::Positive
         }
-        hir::ItemKind::Impl(hir::Impl {
-            polarity: hir::ImplPolarity::Positive,
-            of_trait: Some(_),
-            ..
-        }) => {
+        hir::Impl { polarity: hir::ImplPolarity::Positive, of_trait: Some(_), .. } => {
             if is_rustc_reservation {
                 ty::ImplPolarity::Reservation
             } else {
                 ty::ImplPolarity::Positive
             }
         }
-        item => bug!("impl_polarity: {:?} not an impl", item),
     }
 }
 
diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs
index 14cc8c260e2..8311a735133 100644
--- a/compiler/rustc_incremental/src/persist/dirty_clean.rs
+++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs
@@ -63,7 +63,7 @@ const BASE_HIR: &[&str] = &[
 
 /// `impl` implementation of struct/trait
 const BASE_IMPL: &[&str] =
-    &[label_strs::associated_item_def_ids, label_strs::generics_of, label_strs::impl_trait_ref];
+    &[label_strs::associated_item_def_ids, label_strs::generics_of, label_strs::impl_trait_header];
 
 /// DepNodes for mir_built/Optimized, which is relevant in "executable"
 /// code, i.e., functions+methods
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 988388edfd5..058f28a3ee9 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -215,7 +215,7 @@ provide! { tcx, def_id, other, cdata,
     variances_of => { table }
     fn_sig => { table }
     codegen_fn_attrs => { table }
-    impl_trait_ref => { table }
+    impl_trait_header => { table }
     const_param_default => { table }
     object_lifetime_default => { table }
     thir_abstract_const => { table }
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 6ca1973396f..361c0a3f87e 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1971,8 +1971,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             self.tables.defaultness.set_some(def_id.index, tcx.defaultness(def_id));
             self.tables.impl_polarity.set_some(def_id.index, tcx.impl_polarity(def_id));
 
-            if of_trait && let Some(trait_ref) = tcx.impl_trait_ref(def_id) {
-                record!(self.tables.impl_trait_ref[def_id] <- trait_ref);
+            if of_trait && let Some(header) = tcx.impl_trait_header(def_id) {
+                record!(self.tables.impl_trait_header[def_id] <- header);
+                let (trait_ref, _polarity) = header;
 
                 let trait_ref = trait_ref.instantiate_identity();
                 let simplified_self_ty = fast_reject::simplify_type(
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 8205e995c19..f2d4ae11105 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -423,7 +423,7 @@ define_tables! {
     variances_of: Table<DefIndex, LazyArray<ty::Variance>>,
     fn_sig: Table<DefIndex, LazyValue<ty::EarlyBinder<ty::PolyFnSig<'static>>>>,
     codegen_fn_attrs: Table<DefIndex, LazyValue<CodegenFnAttrs>>,
-    impl_trait_ref: Table<DefIndex, LazyValue<ty::EarlyBinder<ty::TraitRef<'static>>>>,
+    impl_trait_header: Table<DefIndex, LazyValue<(ty::EarlyBinder<ty::TraitRef<'static>>, ty::ImplPolarity)>>,
     const_param_default: Table<DefIndex, LazyValue<ty::EarlyBinder<rustc_middle::ty::Const<'static>>>>,
     object_lifetime_default: Table<DefIndex, LazyValue<ObjectLifetimeDefault>>,
     optimized_mir: Table<DefIndex, LazyValue<mir::Body<'static>>>,
diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs
index a272a51f327..e15a051b33f 100644
--- a/compiler/rustc_middle/src/query/erase.rs
+++ b/compiler/rustc_middle/src/query/erase.rs
@@ -177,8 +177,9 @@ 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::TraitRef<'_>>, ty::ImplPolarity)> {
+    type Result =
+        [u8; size_of::<Option<(ty::EarlyBinder<ty::TraitRef<'static>>, ty::ImplPolarity)>>()];
 }
 
 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 938fba0ed09..59fb198a3da 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -846,9 +846,9 @@ 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::TraitRef<'tcx>>, ty::ImplPolarity)> {
         desc { |tcx| "computing trait implemented by `{}`", tcx.def_path_str(impl_id) }
         cache_on_disk_if { impl_id.is_local() }
         separate_provide_extern
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index b747f0a4fb6..c3b69cee9ed 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -2308,6 +2308,15 @@ 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)?.0)
+    }
 }
 
 /// Parameter attributes that can only be determined by examining the body of a function instead