From 881862ecb79a447c9631becb7f35c1c47b406346 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Tue, 22 Nov 2022 18:12:12 +0000 Subject: [PATCH 1/6] Rename `fn_trait_kind_from_{from_lang=>def_id}` to better convey meaning --- compiler/rustc_hir_typeck/src/closure.rs | 6 +++--- .../error_reporting/nice_region_error/placeholder_error.rs | 2 +- compiler/rustc_middle/src/middle/lang_items.rs | 2 +- compiler/rustc_middle/src/ty/print/pretty.rs | 2 +- compiler/rustc_mir_transform/src/shim.rs | 2 +- .../rustc_trait_selection/src/traits/error_reporting/mod.rs | 2 +- .../src/traits/error_reporting/suggestions.rs | 2 +- .../src/traits/select/candidate_assembly.rs | 4 ++-- .../rustc_trait_selection/src/traits/select/confirmation.rs | 2 +- compiler/rustc_ty_utils/src/instance.rs | 2 +- src/librustdoc/clean/utils.rs | 2 +- 11 files changed, 14 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index e2fefd2724f..11a5f2b0d90 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -178,7 +178,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }); let kind = object_type .principal_def_id() - .and_then(|did| self.tcx.fn_trait_kind_from_lang_item(did)); + .and_then(|did| self.tcx.fn_trait_kind_from_def_id(did)); (sig, kind) } ty::Infer(ty::TyVar(vid)) => self.deduce_signature_from_predicates( @@ -235,7 +235,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => None, }; if let Some(closure_kind) = - trait_def_id.and_then(|def_id| self.tcx.fn_trait_kind_from_lang_item(def_id)) + trait_def_id.and_then(|def_id| self.tcx.fn_trait_kind_from_def_id(def_id)) { expected_kind = Some( expected_kind @@ -263,7 +263,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let trait_def_id = projection.trait_def_id(tcx); - let is_fn = tcx.fn_trait_kind_from_lang_item(trait_def_id).is_some(); + let is_fn = tcx.fn_trait_kind_from_def_id(trait_def_id).is_some(); let gen_trait = tcx.require_lang_item(LangItem::Generator, cause_span); let is_gen = gen_trait == trait_def_id; if !is_fn && !is_gen { diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs index a585168294a..3a74ac51b2c 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -401,7 +401,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { if self_ty.value.is_closure() && self .tcx() - .fn_trait_kind_from_lang_item(expected_trait_ref.value.def_id) + .fn_trait_kind_from_def_id(expected_trait_ref.value.def_id) .is_some() { let closure_sig = self_ty.map(|closure| { diff --git a/compiler/rustc_middle/src/middle/lang_items.rs b/compiler/rustc_middle/src/middle/lang_items.rs index dd4332d0db6..e1bcb74b281 100644 --- a/compiler/rustc_middle/src/middle/lang_items.rs +++ b/compiler/rustc_middle/src/middle/lang_items.rs @@ -27,7 +27,7 @@ impl<'tcx> TyCtxt<'tcx> { }) } - pub fn fn_trait_kind_from_lang_item(self, id: DefId) -> Option { + pub fn fn_trait_kind_from_def_id(self, id: DefId) -> Option { let items = self.lang_items(); match Some(id) { x if x == items.fn_trait() => Some(ty::ClosureKind::Fn), diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index d5e196b2e9f..6afb8bdc457 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1085,7 +1085,7 @@ pub trait PrettyPrinter<'tcx>: let mut resugared = false; // Special-case `Fn(...) -> ...` and re-sugar it. - let fn_trait_kind = cx.tcx().fn_trait_kind_from_lang_item(principal.def_id); + let fn_trait_kind = cx.tcx().fn_trait_kind_from_def_id(principal.def_id); if !cx.should_print_verbose() && fn_trait_kind.is_some() { if let ty::Tuple(tys) = principal.substs.type_at(0).kind() { let mut projections = predicates.projection_bounds(); diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 68703eb0a23..a115bb2831a 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -37,7 +37,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<' } ty::InstanceDef::FnPtrShim(def_id, ty) => { let trait_ = tcx.trait_of_item(def_id).unwrap(); - let adjustment = match tcx.fn_trait_kind_from_lang_item(trait_) { + let adjustment = match tcx.fn_trait_kind_from_def_id(trait_) { Some(ty::ClosureKind::FnOnce) => Adjustment::Identity, Some(ty::ClosureKind::FnMut | ty::ClosureKind::Fn) => Adjustment::Deref, None => bug!("fn pointer {:?} is not an fn", ty), diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 4ac53f6302f..c466e1e29ad 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -2155,7 +2155,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if generics.params.iter().any(|p| p.name != kw::SelfUpper) && !snippet.ends_with('>') && !generics.has_impl_trait() - && !self.tcx.fn_trait_kind_from_lang_item(def_id).is_some() + && !self.tcx.fn_trait_kind_from_def_id(def_id).is_some() { // FIXME: To avoid spurious suggestions in functions where type arguments // where already supplied, we check the snippet to make sure it doesn't diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index da6ca30cc9a..07ba4d0c3b8 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1680,7 +1680,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let inputs = trait_ref.skip_binder().substs.type_at(1); let sig = match inputs.kind() { ty::Tuple(inputs) - if infcx.tcx.fn_trait_kind_from_lang_item(trait_ref.def_id()).is_some() => + if infcx.tcx.fn_trait_kind_from_def_id(trait_ref.def_id()).is_some() => { infcx.tcx.mk_fn_sig( inputs.iter(), diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index f8c7a896b53..460ca923c6e 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -451,7 +451,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation: &TraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, ) { - let Some(kind) = self.tcx().fn_trait_kind_from_lang_item(obligation.predicate.def_id()) else { + let Some(kind) = self.tcx().fn_trait_kind_from_def_id(obligation.predicate.def_id()) else { return; }; @@ -489,7 +489,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { candidates: &mut SelectionCandidateSet<'tcx>, ) { // We provide impl of all fn traits for fn pointers. - if self.tcx().fn_trait_kind_from_lang_item(obligation.predicate.def_id()).is_none() { + if self.tcx().fn_trait_kind_from_def_id(obligation.predicate.def_id()).is_none() { return; } diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 8c589aa8cd1..28e742688a9 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -735,7 +735,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) -> Result>, SelectionError<'tcx>> { let kind = self .tcx() - .fn_trait_kind_from_lang_item(obligation.predicate.def_id()) + .fn_trait_kind_from_def_id(obligation.predicate.def_id()) .unwrap_or_else(|| bug!("closure candidate for non-fn trait {:?}", obligation)); // Okay to skip binder because the substs on closure types never diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 4a887bc5918..c6f2b16ca21 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -209,7 +209,7 @@ fn resolve_associated_item<'tcx>( substs: future_data.substs, }), traits::ImplSource::Closure(closure_data) => { - let trait_closure_kind = tcx.fn_trait_kind_from_lang_item(trait_id).unwrap(); + let trait_closure_kind = tcx.fn_trait_kind_from_def_id(trait_id).unwrap(); Instance::resolve_closure( tcx, closure_data.closure_def_id, diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 35e2720fdff..d540d828d3b 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -106,7 +106,7 @@ fn external_generic_args<'tcx>( ) -> GenericArgs { let args = substs_to_args(cx, substs, has_self); - if cx.tcx.fn_trait_kind_from_lang_item(did).is_some() { + if cx.tcx.fn_trait_kind_from_def_id(did).is_some() { let inputs = // The trait's first substitution is the one after self, if there is one. match substs.iter().nth(if has_self { 1 } else { 0 }).unwrap().expect_ty().kind() { From d0c7ed3beaaef613d2b0676c7808ee818cb8c8bc Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Tue, 22 Nov 2022 18:24:50 +0000 Subject: [PATCH 2/6] Remove `ty::ClosureKind::from_def_id` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …in favour of `TyCtxt::fn_trait_kind_from_def_id` --- compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs | 4 ++-- compiler/rustc_middle/src/ty/closure.rs | 15 +++------------ .../src/traits/error_reporting/mod.rs | 9 +++++---- .../src/traits/error_reporting/suggestions.rs | 4 ++-- 4 files changed, 12 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index ecf6f458ca3..5c7d21fc2e4 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -2089,7 +2089,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let maybe_trait_item_def_id = assoc_item.trait_item_def_id.unwrap_or(def_id) && let maybe_trait_def_id = self.tcx.parent(maybe_trait_item_def_id) // Just an easy way to check "trait_def_id == Fn/FnMut/FnOnce" - && let Some(call_kind) = ty::ClosureKind::from_def_id(self.tcx, maybe_trait_def_id) + && let Some(call_kind) = self.tcx.fn_trait_kind_from_def_id(maybe_trait_def_id) && let Some(callee_ty) = callee_ty { let callee_ty = callee_ty.peel_refs(); @@ -2115,7 +2115,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { if let ty::PredicateKind::Clause(ty::Clause::Trait(pred)) = predicate.kind().skip_binder() && pred.self_ty().peel_refs() == callee_ty - && ty::ClosureKind::from_def_id(self.tcx, pred.def_id()).is_some() + && self.tcx.fn_trait_kind_from_def_id(pred.def_id()).is_some() { err.span_note(span, "callable defined here"); return; diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index 273a61c966c..2653c8576de 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -118,18 +118,9 @@ impl<'tcx> ClosureKind { } } - pub fn from_def_id(tcx: TyCtxt<'_>, def_id: DefId) -> Option { - if Some(def_id) == tcx.lang_items().fn_once_trait() { - Some(ClosureKind::FnOnce) - } else if Some(def_id) == tcx.lang_items().fn_mut_trait() { - Some(ClosureKind::FnMut) - } else if Some(def_id) == tcx.lang_items().fn_trait() { - Some(ClosureKind::Fn) - } else { - None - } - } - + /// Converts `self` to a [`DefId`] of the corresponding trait. + /// + /// Note: the inverse of this function is [`TyCtxt::fn_trait_kind_from_def_id`] pub fn to_def_id(&self, tcx: TyCtxt<'_>) -> DefId { tcx.require_lang_item( match self { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index c466e1e29ad..de35fbfe6d0 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -357,7 +357,8 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { ocx.register_obligation(obligation); if ocx.select_all_or_error().is_empty() { return Ok(( - ty::ClosureKind::from_def_id(self.tcx, trait_def_id) + self.tcx + .fn_trait_kind_from_def_id(trait_def_id) .expect("expected to map DefId to ClosureKind"), ty.rebind(self.resolve_vars_if_possible(var)), )); @@ -686,7 +687,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } ObligationCauseCode::BindingObligation(def_id, _) | ObligationCauseCode::ItemObligation(def_id) - if ty::ClosureKind::from_def_id(tcx, *def_id).is_some() => + if tcx.fn_trait_kind_from_def_id(*def_id).is_some() => { err.code(rustc_errors::error_code!(E0059)); err.set_primary_message(format!( @@ -847,7 +848,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } let is_fn_trait = - ty::ClosureKind::from_def_id(tcx, trait_ref.def_id()).is_some(); + tcx.fn_trait_kind_from_def_id(trait_ref.def_id()).is_some(); let is_target_feature_fn = if let ty::FnDef(def_id, _) = *trait_ref.skip_binder().self_ty().kind() { @@ -877,7 +878,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // Note if the `FnMut` or `FnOnce` is less general than the trait we're trying // to implement. let selected_kind = - ty::ClosureKind::from_def_id(self.tcx, trait_ref.def_id()) + self.tcx.fn_trait_kind_from_def_id(trait_ref.def_id()) .expect("expected to map DefId to ClosureKind"); if !implemented_kind.extends(selected_kind) { err.note( diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 07ba4d0c3b8..4ae9b22f221 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1752,7 +1752,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { && let predicates = self.tcx.predicates_of(def_id).instantiate_identity(self.tcx) && let Some(pred) = predicates.predicates.get(*idx) && let ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) = pred.kind().skip_binder() - && ty::ClosureKind::from_def_id(self.tcx, trait_pred.def_id()).is_some() + && self.tcx.fn_trait_kind_from_def_id(trait_pred.def_id()).is_some() { let expected_self = self.tcx.anonymize_late_bound_regions(pred.kind().rebind(trait_pred.self_ty())); @@ -1766,7 +1766,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { .enumerate() .find(|(other_idx, (pred, _))| match pred.kind().skip_binder() { ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) - if ty::ClosureKind::from_def_id(self.tcx, trait_pred.def_id()) + if self.tcx.fn_trait_kind_from_def_id(trait_pred.def_id()) .is_some() && other_idx != idx // Make sure that the self type matches From 4b6e1d1c5fc9eaedc119759d99b6105b4f7f5d1e Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Tue, 22 Nov 2022 18:31:23 +0000 Subject: [PATCH 3/6] Add `TyCtxt::is_fn_trait` --- compiler/rustc_hir_typeck/src/closure.rs | 2 +- compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs | 2 +- compiler/rustc_middle/src/middle/lang_items.rs | 8 ++++++++ .../src/traits/error_reporting/mod.rs | 7 +++---- .../src/traits/error_reporting/suggestions.rs | 6 ++---- .../src/traits/select/candidate_assembly.rs | 2 +- 6 files changed, 16 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index 11a5f2b0d90..e584d413c41 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -263,7 +263,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let trait_def_id = projection.trait_def_id(tcx); - let is_fn = tcx.fn_trait_kind_from_def_id(trait_def_id).is_some(); + let is_fn = tcx.is_fn_trait(trait_def_id); let gen_trait = tcx.require_lang_item(LangItem::Generator, cause_span); let is_gen = gen_trait == trait_def_id; if !is_fn && !is_gen { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 5c7d21fc2e4..86384c7b93e 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -2115,7 +2115,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { if let ty::PredicateKind::Clause(ty::Clause::Trait(pred)) = predicate.kind().skip_binder() && pred.self_ty().peel_refs() == callee_ty - && self.tcx.fn_trait_kind_from_def_id(pred.def_id()).is_some() + && self.tcx.is_fn_trait(pred.def_id()) { err.span_note(span, "callable defined here"); return; diff --git a/compiler/rustc_middle/src/middle/lang_items.rs b/compiler/rustc_middle/src/middle/lang_items.rs index e1bcb74b281..343ea1f00f5 100644 --- a/compiler/rustc_middle/src/middle/lang_items.rs +++ b/compiler/rustc_middle/src/middle/lang_items.rs @@ -27,6 +27,9 @@ impl<'tcx> TyCtxt<'tcx> { }) } + /// Given a [`DefId`] of a [`Fn`], [`FnMut`] or [`FnOnce`] traits, + /// returns a corresponding [`ty::ClosureKind`]. + /// For any other [`DefId`] return `None`. pub fn fn_trait_kind_from_def_id(self, id: DefId) -> Option { let items = self.lang_items(); match Some(id) { @@ -36,6 +39,11 @@ impl<'tcx> TyCtxt<'tcx> { _ => None, } } + + /// Returns `true` if `id` is a `DefId` of [`Fn`], [`FnMut`] or [`FnOnce`] traits. + pub fn is_fn_trait(self, id: DefId) -> bool { + self.fn_trait_kind_from_def_id(id).is_some() + } } /// Returns `true` if the specified `lang_item` must be present for this diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index de35fbfe6d0..e96b9b64e78 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -687,7 +687,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } ObligationCauseCode::BindingObligation(def_id, _) | ObligationCauseCode::ItemObligation(def_id) - if tcx.fn_trait_kind_from_def_id(*def_id).is_some() => + if tcx.is_fn_trait(*def_id) => { err.code(rustc_errors::error_code!(E0059)); err.set_primary_message(format!( @@ -847,8 +847,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ); } - let is_fn_trait = - tcx.fn_trait_kind_from_def_id(trait_ref.def_id()).is_some(); + let is_fn_trait = tcx.is_fn_trait(trait_ref.def_id()); let is_target_feature_fn = if let ty::FnDef(def_id, _) = *trait_ref.skip_binder().self_ty().kind() { @@ -2156,7 +2155,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if generics.params.iter().any(|p| p.name != kw::SelfUpper) && !snippet.ends_with('>') && !generics.has_impl_trait() - && !self.tcx.fn_trait_kind_from_def_id(def_id).is_some() + && !self.tcx.is_fn_trait(def_id) { // FIXME: To avoid spurious suggestions in functions where type arguments // where already supplied, we check the snippet to make sure it doesn't diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 4ae9b22f221..ddffe25bc26 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1679,9 +1679,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ) -> Ty<'tcx> { let inputs = trait_ref.skip_binder().substs.type_at(1); let sig = match inputs.kind() { - ty::Tuple(inputs) - if infcx.tcx.fn_trait_kind_from_def_id(trait_ref.def_id()).is_some() => - { + ty::Tuple(inputs) if infcx.tcx.is_fn_trait(trait_ref.def_id()) => { infcx.tcx.mk_fn_sig( inputs.iter(), infcx.next_ty_var(TypeVariableOrigin { @@ -1752,7 +1750,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { && let predicates = self.tcx.predicates_of(def_id).instantiate_identity(self.tcx) && let Some(pred) = predicates.predicates.get(*idx) && let ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) = pred.kind().skip_binder() - && self.tcx.fn_trait_kind_from_def_id(trait_pred.def_id()).is_some() + && self.tcx.is_fn_trait(trait_pred.def_id()) { let expected_self = self.tcx.anonymize_late_bound_regions(pred.kind().rebind(trait_pred.self_ty())); diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 460ca923c6e..adce549a858 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -489,7 +489,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { candidates: &mut SelectionCandidateSet<'tcx>, ) { // We provide impl of all fn traits for fn pointers. - if self.tcx().fn_trait_kind_from_def_id(obligation.predicate.def_id()).is_none() { + if !self.tcx().is_fn_trait(obligation.predicate.def_id()) { return; } From fa89f533524ba41589b211845f19a75811330efc Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Tue, 22 Nov 2022 18:35:58 +0000 Subject: [PATCH 4/6] Simplify `ty::ClosureKind::extends` This is valid per the comment of the `ClosureKind` defition --- compiler/rustc_middle/src/ty/closure.rs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index 2653c8576de..e0bd4909810 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -97,15 +97,7 @@ impl<'tcx> ClosureKind { /// Returns `true` if a type that impls this closure kind /// must also implement `other`. pub fn extends(self, other: ty::ClosureKind) -> bool { - matches!( - (self, other), - (ClosureKind::Fn, ClosureKind::Fn) - | (ClosureKind::Fn, ClosureKind::FnMut) - | (ClosureKind::Fn, ClosureKind::FnOnce) - | (ClosureKind::FnMut, ClosureKind::FnMut) - | (ClosureKind::FnMut, ClosureKind::FnOnce) - | (ClosureKind::FnOnce, ClosureKind::FnOnce) - ) + self <= other } /// Returns the representative scalar type for this closure kind. From ea447924cef96746d27c396d395cc5cfea738928 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Tue, 22 Nov 2022 18:52:07 +0000 Subject: [PATCH 5/6] micro doc fixes --- compiler/rustc_middle/src/ty/closure.rs | 22 +++++++++++----------- compiler/rustc_middle/src/ty/sty.rs | 3 +-- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index e0bd4909810..286946d1d1f 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -100,19 +100,9 @@ impl<'tcx> ClosureKind { self <= other } - /// Returns the representative scalar type for this closure kind. - /// See `Ty::to_opt_closure_kind` for more details. - pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { - match self { - ClosureKind::Fn => tcx.types.i8, - ClosureKind::FnMut => tcx.types.i16, - ClosureKind::FnOnce => tcx.types.i32, - } - } - /// Converts `self` to a [`DefId`] of the corresponding trait. /// - /// Note: the inverse of this function is [`TyCtxt::fn_trait_kind_from_def_id`] + /// Note: the inverse of this function is [`TyCtxt::fn_trait_kind_from_def_id`]. pub fn to_def_id(&self, tcx: TyCtxt<'_>) -> DefId { tcx.require_lang_item( match self { @@ -123,6 +113,16 @@ impl<'tcx> ClosureKind { None, ) } + + /// Returns the representative scalar type for this closure kind. + /// See `Ty::to_opt_closure_kind` for more details. + pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { + match self { + ClosureKind::Fn => tcx.types.i8, + ClosureKind::FnMut => tcx.types.i16, + ClosureKind::FnOnce => tcx.types.i32, + } + } } /// A composite describing a `Place` that is captured by a closure. diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index a53b275fb02..4fc97c0baaf 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -2114,8 +2114,7 @@ impl<'tcx> Ty<'tcx> { /// parameter. This is kind of a phantom type, except that the /// most convenient thing for us to are the integral types. This /// function converts such a special type into the closure - /// kind. To go the other way, use - /// `tcx.closure_kind_ty(closure_kind)`. + /// kind. To go the other way, use `closure_kind.to_ty(tcx)`. /// /// Note that during type checking, we use an inference variable /// to represent the closure kind, because it has not yet been From 5ba0056346a745e61cb2cb90d69a3304a255ff42 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Tue, 22 Nov 2022 19:03:26 +0000 Subject: [PATCH 6/6] Use `TyCtxt::is_fn_trait` is a couple more places --- .../error_reporting/nice_region_error/placeholder_error.rs | 5 +---- .../src/traits/error_reporting/suggestions.rs | 3 +-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs index 3a74ac51b2c..1f554c81eff 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -399,10 +399,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { self_ty.highlight.maybe_highlighting_region(vid, actual_has_vid); if self_ty.value.is_closure() - && self - .tcx() - .fn_trait_kind_from_def_id(expected_trait_ref.value.def_id) - .is_some() + && self.tcx().is_fn_trait(expected_trait_ref.value.def_id) { let closure_sig = self_ty.map(|closure| { if let ty::Closure(_, substs) = closure.kind() { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index ddffe25bc26..2cb04b94954 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1764,8 +1764,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { .enumerate() .find(|(other_idx, (pred, _))| match pred.kind().skip_binder() { ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) - if self.tcx.fn_trait_kind_from_def_id(trait_pred.def_id()) - .is_some() + if self.tcx.is_fn_trait(trait_pred.def_id()) && other_idx != idx // Make sure that the self type matches // (i.e. constraining this closure)