From b0f6698a86c0a3c95bccc71a81471bc926dd4e52 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 23 Nov 2024 04:48:01 +0000 Subject: [PATCH 1/3] Make compare_impl_item into a query --- .../rustc_hir_analysis/src/check/check.rs | 18 +---- .../src/check/compare_impl_item.rs | 74 +++++++++++-------- compiler/rustc_hir_analysis/src/check/mod.rs | 2 +- compiler/rustc_middle/src/query/mod.rs | 4 +- compiler/rustc_ty_utils/src/instance.rs | 10 +-- .../const-generics/issues/issue-83765.stderr | 8 +- 6 files changed, 56 insertions(+), 60 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index c66572a937726..3598215266005 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -33,7 +33,7 @@ use tracing::{debug, instrument}; use ty::TypingMode; use {rustc_attr as attr, rustc_hir as hir}; -use super::compare_impl_item::{check_type_bounds, compare_impl_method, compare_impl_ty}; +use super::compare_impl_item::check_type_bounds; use super::*; use crate::check::intrinsicck::InlineAsmCtxt; @@ -1036,20 +1036,8 @@ fn check_impl_items_against_trait<'tcx>( tcx.dcx().span_delayed_bug(tcx.def_span(impl_item), "missing associated item in trait"); continue; }; - match ty_impl_item.kind { - ty::AssocKind::Const => { - tcx.ensure().compare_impl_const(( - impl_item.expect_local(), - ty_impl_item.trait_item_def_id.unwrap(), - )); - } - ty::AssocKind::Fn => { - compare_impl_method(tcx, ty_impl_item, ty_trait_item, trait_ref); - } - ty::AssocKind::Type => { - compare_impl_ty(tcx, ty_impl_item, ty_trait_item, trait_ref); - } - } + + tcx.ensure().compare_impl_item((impl_item.expect_local(), ty_trait_item.def_id)); check_specialization_validity( tcx, diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index bd0b0ceb92d5d..4ed517f6455ae 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -35,6 +35,26 @@ use crate::errors::{LifetimesOrBoundsMismatchOnTrait, MethodShouldReturnFuture}; mod refine; +/// Call the query `tcx.compare_impl_item()` directly instead. +pub(super) fn compare_impl_item( + tcx: TyCtxt<'_>, + (impl_item_def_id, trait_item_def_id): (LocalDefId, DefId), +) -> Result<(), ErrorGuaranteed> { + let impl_item = tcx.associated_item(impl_item_def_id); + let trait_item = tcx.associated_item(trait_item_def_id); + let impl_trait_ref = + tcx.impl_trait_ref(impl_item.container_id(tcx)).unwrap().instantiate_identity(); + debug!(?impl_trait_ref); + + match impl_item.kind { + ty::AssocKind::Fn => compare_impl_method_inner(tcx, impl_item, trait_item, impl_trait_ref), + ty::AssocKind::Type => compare_impl_ty_inner(tcx, impl_item, trait_item, impl_trait_ref), + ty::AssocKind::Const => { + compare_impl_const_inner(tcx, impl_item, trait_item, impl_trait_ref) + } + } +} + /// Checks that a method from an impl conforms to the signature of /// the same method as declared in the trait. /// @@ -44,22 +64,21 @@ mod refine; /// - `trait_m`: the method in the trait /// - `impl_trait_ref`: the TraitRef corresponding to the trait implementation #[instrument(level = "debug", skip(tcx))] -pub(super) fn compare_impl_method<'tcx>( +pub(super) fn compare_impl_method_inner<'tcx>( tcx: TyCtxt<'tcx>, impl_m: ty::AssocItem, trait_m: ty::AssocItem, impl_trait_ref: ty::TraitRef<'tcx>, -) { - let _: Result<_, ErrorGuaranteed> = try { - check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, false)?; - compare_method_predicate_entailment(tcx, impl_m, trait_m, impl_trait_ref)?; - refine::check_refining_return_position_impl_trait_in_trait( - tcx, - impl_m, - trait_m, - impl_trait_ref, - ); - }; +) -> Result<(), ErrorGuaranteed> { + check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, false)?; + compare_method_predicate_entailment(tcx, impl_m, trait_m, impl_trait_ref)?; + refine::check_refining_return_position_impl_trait_in_trait( + tcx, + impl_m, + trait_m, + impl_trait_ref, + ); + Ok(()) } /// Checks a bunch of different properties of the impl/trait methods for @@ -1727,17 +1746,12 @@ fn compare_generic_param_kinds<'tcx>( Ok(()) } -/// Use `tcx.compare_impl_const` instead -pub(super) fn compare_impl_const_raw( - tcx: TyCtxt<'_>, - (impl_const_item_def, trait_const_item_def): (LocalDefId, DefId), +fn compare_impl_const_inner<'tcx>( + tcx: TyCtxt<'tcx>, + impl_const_item: ty::AssocItem, + trait_const_item: ty::AssocItem, + impl_trait_ref: ty::TraitRef<'tcx>, ) -> Result<(), ErrorGuaranteed> { - let impl_const_item = tcx.associated_item(impl_const_item_def); - let trait_const_item = tcx.associated_item(trait_const_item_def); - let impl_trait_ref = - tcx.impl_trait_ref(impl_const_item.container_id(tcx)).unwrap().instantiate_identity(); - debug!(?impl_trait_ref); - compare_number_of_generics(tcx, impl_const_item, trait_const_item, false)?; compare_generic_param_kinds(tcx, impl_const_item, trait_const_item, false)?; check_region_bounds_on_impl_item(tcx, impl_const_item, trait_const_item, false)?; @@ -1868,19 +1882,17 @@ fn compare_const_predicate_entailment<'tcx>( } #[instrument(level = "debug", skip(tcx))] -pub(super) fn compare_impl_ty<'tcx>( +pub(super) fn compare_impl_ty_inner<'tcx>( tcx: TyCtxt<'tcx>, impl_ty: ty::AssocItem, trait_ty: ty::AssocItem, impl_trait_ref: ty::TraitRef<'tcx>, -) { - let _: Result<(), ErrorGuaranteed> = try { - compare_number_of_generics(tcx, impl_ty, trait_ty, false)?; - compare_generic_param_kinds(tcx, impl_ty, trait_ty, false)?; - check_region_bounds_on_impl_item(tcx, impl_ty, trait_ty, false)?; - compare_type_predicate_entailment(tcx, impl_ty, trait_ty, impl_trait_ref)?; - check_type_bounds(tcx, trait_ty, impl_ty, impl_trait_ref)?; - }; +) -> Result<(), ErrorGuaranteed> { + compare_number_of_generics(tcx, impl_ty, trait_ty, false)?; + compare_generic_param_kinds(tcx, impl_ty, trait_ty, false)?; + check_region_bounds_on_impl_item(tcx, impl_ty, trait_ty, false)?; + compare_type_predicate_entailment(tcx, impl_ty, trait_ty, impl_trait_ref)?; + check_type_bounds(tcx, trait_ty, impl_ty, impl_trait_ref) } /// The equivalent of [compare_method_predicate_entailment], but for associated types diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 375cbfd1c4fb8..61e203a1ff668 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -108,7 +108,7 @@ pub fn provide(providers: &mut Providers) { adt_async_destructor, region_scope_tree, collect_return_position_impl_trait_in_trait_tys, - compare_impl_const: compare_impl_item::compare_impl_const_raw, + compare_impl_item: compare_impl_item::compare_impl_item, check_coroutine_obligations: check::check_coroutine_obligations, ..*providers }; diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 76338be33aad8..0e99ceb133c9b 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -2309,10 +2309,10 @@ rustc_queries! { desc { "checking validity requirement for `{}`: {}", key.1.value, key.0 } } - query compare_impl_const( + query compare_impl_item( key: (LocalDefId, DefId) ) -> Result<(), ErrorGuaranteed> { - desc { |tcx| "checking assoc const `{}` has the same type as trait item", tcx.def_path_str(key.0) } + desc { |tcx| "checking assoc item `{}` is compatible with trait definition", tcx.def_path_str(key.0) } } query deduced_param_attrs(def_id: DefId) -> &'tcx [ty::DeducedParamAttrs] { diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 29fc92e1f2f92..6608996f325a1 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -213,15 +213,11 @@ fn resolve_associated_item<'tcx>( let args = tcx.erase_regions(args); - // Check if we just resolved an associated `const` declaration from - // a `trait` to an associated `const` definition in an `impl`, where - // the definition in the `impl` has the wrong type (for which an - // error has already been/will be emitted elsewhere). - if leaf_def.item.kind == ty::AssocKind::Const - && trait_item_id != leaf_def.item.def_id + // Meow + if trait_item_id != leaf_def.item.def_id && let Some(leaf_def_item) = leaf_def.item.def_id.as_local() { - tcx.compare_impl_const((leaf_def_item, trait_item_id))?; + tcx.compare_impl_item((leaf_def_item, trait_item_id))?; } Some(ty::Instance::new(leaf_def.item.def_id, args)) diff --git a/tests/ui/const-generics/issues/issue-83765.stderr b/tests/ui/const-generics/issues/issue-83765.stderr index c3292314f23b3..cce627499125b 100644 --- a/tests/ui/const-generics/issues/issue-83765.stderr +++ b/tests/ui/const-generics/issues/issue-83765.stderr @@ -29,11 +29,11 @@ note: ...which requires computing candidate for `::DIM, DIM> as TensorDimension>::DIM`, completing the cycle -note: cycle used when checking that `` is well-formed - --> $DIR/issue-83765.rs:56:1 +note: cycle used when checking assoc item `::bget` is compatible with trait definition + --> $DIR/issue-83765.rs:58:5 | -LL | impl<'a, T: Broadcastable, const DIM: usize> Broadcastable for LazyUpdim<'a, T, { T::DIM }, DIM> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn bget(&self, index: [usize; DIM]) -> Option { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error[E0308]: method not compatible with trait From 1b30977a1c97aa9e204670f98d777047421102a6 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 23 Nov 2024 15:39:45 +0000 Subject: [PATCH 2/3] Cache better --- compiler/rustc_middle/src/query/mod.rs | 2 ++ compiler/rustc_ty_utils/src/instance.rs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 0e99ceb133c9b..0e5b5b2363c32 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -2313,6 +2313,8 @@ rustc_queries! { key: (LocalDefId, DefId) ) -> Result<(), ErrorGuaranteed> { desc { |tcx| "checking assoc item `{}` is compatible with trait definition", tcx.def_path_str(key.0) } + cache_on_disk_if { true } + ensure_forwards_result_if_red } query deduced_param_attrs(def_id: DefId) -> &'tcx [ty::DeducedParamAttrs] { diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 6608996f325a1..61b0ab2bba414 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -217,7 +217,7 @@ fn resolve_associated_item<'tcx>( if trait_item_id != leaf_def.item.def_id && let Some(leaf_def_item) = leaf_def.item.def_id.as_local() { - tcx.compare_impl_item((leaf_def_item, trait_item_id))?; + tcx.ensure().compare_impl_item((leaf_def_item, trait_item_id))?; } Some(ty::Instance::new(leaf_def.item.def_id, args)) From 4ece9e6ca94de71f34400fcbb97ea582f23a0cb4 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 23 Nov 2024 16:05:10 +0000 Subject: [PATCH 3/3] Stop passing a redundant key --- compiler/rustc_hir_analysis/src/check/check.rs | 2 +- compiler/rustc_hir_analysis/src/check/compare_impl_item.rs | 4 ++-- compiler/rustc_middle/src/query/mod.rs | 4 ++-- compiler/rustc_ty_utils/src/instance.rs | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 3598215266005..032e8c3365a3a 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -1037,7 +1037,7 @@ fn check_impl_items_against_trait<'tcx>( continue; }; - tcx.ensure().compare_impl_item((impl_item.expect_local(), ty_trait_item.def_id)); + let _ = tcx.ensure().compare_impl_item(impl_item.expect_local()); check_specialization_validity( tcx, diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 4ed517f6455ae..d41b040ea1a18 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -38,10 +38,10 @@ mod refine; /// Call the query `tcx.compare_impl_item()` directly instead. pub(super) fn compare_impl_item( tcx: TyCtxt<'_>, - (impl_item_def_id, trait_item_def_id): (LocalDefId, DefId), + impl_item_def_id: LocalDefId, ) -> Result<(), ErrorGuaranteed> { let impl_item = tcx.associated_item(impl_item_def_id); - let trait_item = tcx.associated_item(trait_item_def_id); + let trait_item = tcx.associated_item(impl_item.trait_item_def_id.unwrap()); let impl_trait_ref = tcx.impl_trait_ref(impl_item.container_id(tcx)).unwrap().instantiate_identity(); debug!(?impl_trait_ref); diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 0e5b5b2363c32..519a914ff062e 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -2310,9 +2310,9 @@ rustc_queries! { } query compare_impl_item( - key: (LocalDefId, DefId) + key: LocalDefId ) -> Result<(), ErrorGuaranteed> { - desc { |tcx| "checking assoc item `{}` is compatible with trait definition", tcx.def_path_str(key.0) } + desc { |tcx| "checking assoc item `{}` is compatible with trait definition", tcx.def_path_str(key) } cache_on_disk_if { true } ensure_forwards_result_if_red } diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 61b0ab2bba414..f13d9b10b1fcb 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -217,7 +217,7 @@ fn resolve_associated_item<'tcx>( if trait_item_id != leaf_def.item.def_id && let Some(leaf_def_item) = leaf_def.item.def_id.as_local() { - tcx.ensure().compare_impl_item((leaf_def_item, trait_item_id))?; + tcx.ensure().compare_impl_item(leaf_def_item)?; } Some(ty::Instance::new(leaf_def.item.def_id, args))