Skip to content

Commit f90484d

Browse files
authored
Rollup merge of #104732 - WaffleLapkin:from_def_idn't, r=compiler-errors
Refactor `ty::ClosureKind` related stuff I've tried to fix all duplication and weirdness, but if I missed something do tell :p r? `@compiler-errors`
2 parents f33d409 + 5ba0056 commit f90484d

File tree

14 files changed

+46
-62
lines changed

14 files changed

+46
-62
lines changed

compiler/rustc_hir_typeck/src/closure.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
178178
});
179179
let kind = object_type
180180
.principal_def_id()
181-
.and_then(|did| self.tcx.fn_trait_kind_from_lang_item(did));
181+
.and_then(|did| self.tcx.fn_trait_kind_from_def_id(did));
182182
(sig, kind)
183183
}
184184
ty::Infer(ty::TyVar(vid)) => self.deduce_signature_from_predicates(
@@ -235,7 +235,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
235235
_ => None,
236236
};
237237
if let Some(closure_kind) =
238-
trait_def_id.and_then(|def_id| self.tcx.fn_trait_kind_from_lang_item(def_id))
238+
trait_def_id.and_then(|def_id| self.tcx.fn_trait_kind_from_def_id(def_id))
239239
{
240240
expected_kind = Some(
241241
expected_kind
@@ -263,7 +263,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
263263

264264
let trait_def_id = projection.trait_def_id(tcx);
265265

266-
let is_fn = tcx.fn_trait_kind_from_lang_item(trait_def_id).is_some();
266+
let is_fn = tcx.is_fn_trait(trait_def_id);
267267
let gen_trait = tcx.require_lang_item(LangItem::Generator, cause_span);
268268
let is_gen = gen_trait == trait_def_id;
269269
if !is_fn && !is_gen {

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2089,7 +2089,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20892089
&& let maybe_trait_item_def_id = assoc_item.trait_item_def_id.unwrap_or(def_id)
20902090
&& let maybe_trait_def_id = self.tcx.parent(maybe_trait_item_def_id)
20912091
// Just an easy way to check "trait_def_id == Fn/FnMut/FnOnce"
2092-
&& let Some(call_kind) = ty::ClosureKind::from_def_id(self.tcx, maybe_trait_def_id)
2092+
&& let Some(call_kind) = self.tcx.fn_trait_kind_from_def_id(maybe_trait_def_id)
20932093
&& let Some(callee_ty) = callee_ty
20942094
{
20952095
let callee_ty = callee_ty.peel_refs();
@@ -2115,7 +2115,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21152115
{
21162116
if let ty::PredicateKind::Clause(ty::Clause::Trait(pred)) = predicate.kind().skip_binder()
21172117
&& pred.self_ty().peel_refs() == callee_ty
2118-
&& ty::ClosureKind::from_def_id(self.tcx, pred.def_id()).is_some()
2118+
&& self.tcx.is_fn_trait(pred.def_id())
21192119
{
21202120
err.span_note(span, "callable defined here");
21212121
return;

compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -399,10 +399,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
399399
self_ty.highlight.maybe_highlighting_region(vid, actual_has_vid);
400400

401401
if self_ty.value.is_closure()
402-
&& self
403-
.tcx()
404-
.fn_trait_kind_from_lang_item(expected_trait_ref.value.def_id)
405-
.is_some()
402+
&& self.tcx().is_fn_trait(expected_trait_ref.value.def_id)
406403
{
407404
let closure_sig = self_ty.map(|closure| {
408405
if let ty::Closure(_, substs) = closure.kind() {

compiler/rustc_middle/src/middle/lang_items.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ impl<'tcx> TyCtxt<'tcx> {
2727
})
2828
}
2929

30-
pub fn fn_trait_kind_from_lang_item(self, id: DefId) -> Option<ty::ClosureKind> {
30+
/// Given a [`DefId`] of a [`Fn`], [`FnMut`] or [`FnOnce`] traits,
31+
/// returns a corresponding [`ty::ClosureKind`].
32+
/// For any other [`DefId`] return `None`.
33+
pub fn fn_trait_kind_from_def_id(self, id: DefId) -> Option<ty::ClosureKind> {
3134
let items = self.lang_items();
3235
match Some(id) {
3336
x if x == items.fn_trait() => Some(ty::ClosureKind::Fn),
@@ -36,6 +39,11 @@ impl<'tcx> TyCtxt<'tcx> {
3639
_ => None,
3740
}
3841
}
42+
43+
/// Returns `true` if `id` is a `DefId` of [`Fn`], [`FnMut`] or [`FnOnce`] traits.
44+
pub fn is_fn_trait(self, id: DefId) -> bool {
45+
self.fn_trait_kind_from_def_id(id).is_some()
46+
}
3947
}
4048

4149
/// Returns `true` if the specified `lang_item` must be present for this

compiler/rustc_middle/src/ty/closure.rs

+14-31
Original file line numberDiff line numberDiff line change
@@ -97,39 +97,12 @@ impl<'tcx> ClosureKind {
9797
/// Returns `true` if a type that impls this closure kind
9898
/// must also implement `other`.
9999
pub fn extends(self, other: ty::ClosureKind) -> bool {
100-
matches!(
101-
(self, other),
102-
(ClosureKind::Fn, ClosureKind::Fn)
103-
| (ClosureKind::Fn, ClosureKind::FnMut)
104-
| (ClosureKind::Fn, ClosureKind::FnOnce)
105-
| (ClosureKind::FnMut, ClosureKind::FnMut)
106-
| (ClosureKind::FnMut, ClosureKind::FnOnce)
107-
| (ClosureKind::FnOnce, ClosureKind::FnOnce)
108-
)
109-
}
110-
111-
/// Returns the representative scalar type for this closure kind.
112-
/// See `Ty::to_opt_closure_kind` for more details.
113-
pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
114-
match self {
115-
ClosureKind::Fn => tcx.types.i8,
116-
ClosureKind::FnMut => tcx.types.i16,
117-
ClosureKind::FnOnce => tcx.types.i32,
118-
}
119-
}
120-
121-
pub fn from_def_id(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ClosureKind> {
122-
if Some(def_id) == tcx.lang_items().fn_once_trait() {
123-
Some(ClosureKind::FnOnce)
124-
} else if Some(def_id) == tcx.lang_items().fn_mut_trait() {
125-
Some(ClosureKind::FnMut)
126-
} else if Some(def_id) == tcx.lang_items().fn_trait() {
127-
Some(ClosureKind::Fn)
128-
} else {
129-
None
130-
}
100+
self <= other
131101
}
132102

103+
/// Converts `self` to a [`DefId`] of the corresponding trait.
104+
///
105+
/// Note: the inverse of this function is [`TyCtxt::fn_trait_kind_from_def_id`].
133106
pub fn to_def_id(&self, tcx: TyCtxt<'_>) -> DefId {
134107
tcx.require_lang_item(
135108
match self {
@@ -140,6 +113,16 @@ impl<'tcx> ClosureKind {
140113
None,
141114
)
142115
}
116+
117+
/// Returns the representative scalar type for this closure kind.
118+
/// See `Ty::to_opt_closure_kind` for more details.
119+
pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
120+
match self {
121+
ClosureKind::Fn => tcx.types.i8,
122+
ClosureKind::FnMut => tcx.types.i16,
123+
ClosureKind::FnOnce => tcx.types.i32,
124+
}
125+
}
143126
}
144127

145128
/// A composite describing a `Place` that is captured by a closure.

compiler/rustc_middle/src/ty/print/pretty.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1080,7 +1080,7 @@ pub trait PrettyPrinter<'tcx>:
10801080
let mut resugared = false;
10811081

10821082
// Special-case `Fn(...) -> ...` and re-sugar it.
1083-
let fn_trait_kind = cx.tcx().fn_trait_kind_from_lang_item(principal.def_id);
1083+
let fn_trait_kind = cx.tcx().fn_trait_kind_from_def_id(principal.def_id);
10841084
if !cx.should_print_verbose() && fn_trait_kind.is_some() {
10851085
if let ty::Tuple(tys) = principal.substs.type_at(0).kind() {
10861086
let mut projections = predicates.projection_bounds();

compiler/rustc_middle/src/ty/sty.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -2116,8 +2116,7 @@ impl<'tcx> Ty<'tcx> {
21162116
/// parameter. This is kind of a phantom type, except that the
21172117
/// most convenient thing for us to are the integral types. This
21182118
/// function converts such a special type into the closure
2119-
/// kind. To go the other way, use
2120-
/// `tcx.closure_kind_ty(closure_kind)`.
2119+
/// kind. To go the other way, use `closure_kind.to_ty(tcx)`.
21212120
///
21222121
/// Note that during type checking, we use an inference variable
21232122
/// to represent the closure kind, because it has not yet been

compiler/rustc_mir_transform/src/shim.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'
3737
}
3838
ty::InstanceDef::FnPtrShim(def_id, ty) => {
3939
let trait_ = tcx.trait_of_item(def_id).unwrap();
40-
let adjustment = match tcx.fn_trait_kind_from_lang_item(trait_) {
40+
let adjustment = match tcx.fn_trait_kind_from_def_id(trait_) {
4141
Some(ty::ClosureKind::FnOnce) => Adjustment::Identity,
4242
Some(ty::ClosureKind::FnMut | ty::ClosureKind::Fn) => Adjustment::Deref,
4343
None => bug!("fn pointer {:?} is not an fn", ty),

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,8 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
357357
ocx.register_obligation(obligation);
358358
if ocx.select_all_or_error().is_empty() {
359359
return Ok((
360-
ty::ClosureKind::from_def_id(self.tcx, trait_def_id)
360+
self.tcx
361+
.fn_trait_kind_from_def_id(trait_def_id)
361362
.expect("expected to map DefId to ClosureKind"),
362363
ty.rebind(self.resolve_vars_if_possible(var)),
363364
));
@@ -686,7 +687,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
686687
}
687688
ObligationCauseCode::BindingObligation(def_id, _)
688689
| ObligationCauseCode::ItemObligation(def_id)
689-
if ty::ClosureKind::from_def_id(tcx, *def_id).is_some() =>
690+
if tcx.is_fn_trait(*def_id) =>
690691
{
691692
err.code(rustc_errors::error_code!(E0059));
692693
err.set_primary_message(format!(
@@ -846,8 +847,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
846847
);
847848
}
848849

849-
let is_fn_trait =
850-
ty::ClosureKind::from_def_id(tcx, trait_ref.def_id()).is_some();
850+
let is_fn_trait = tcx.is_fn_trait(trait_ref.def_id());
851851
let is_target_feature_fn = if let ty::FnDef(def_id, _) =
852852
*trait_ref.skip_binder().self_ty().kind()
853853
{
@@ -877,7 +877,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
877877
// Note if the `FnMut` or `FnOnce` is less general than the trait we're trying
878878
// to implement.
879879
let selected_kind =
880-
ty::ClosureKind::from_def_id(self.tcx, trait_ref.def_id())
880+
self.tcx.fn_trait_kind_from_def_id(trait_ref.def_id())
881881
.expect("expected to map DefId to ClosureKind");
882882
if !implemented_kind.extends(selected_kind) {
883883
err.note(
@@ -2155,7 +2155,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
21552155
if generics.params.iter().any(|p| p.name != kw::SelfUpper)
21562156
&& !snippet.ends_with('>')
21572157
&& !generics.has_impl_trait()
2158-
&& !self.tcx.fn_trait_kind_from_lang_item(def_id).is_some()
2158+
&& !self.tcx.is_fn_trait(def_id)
21592159
{
21602160
// FIXME: To avoid spurious suggestions in functions where type arguments
21612161
// where already supplied, we check the snippet to make sure it doesn't

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -1679,9 +1679,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
16791679
) -> Ty<'tcx> {
16801680
let inputs = trait_ref.skip_binder().substs.type_at(1);
16811681
let sig = match inputs.kind() {
1682-
ty::Tuple(inputs)
1683-
if infcx.tcx.fn_trait_kind_from_lang_item(trait_ref.def_id()).is_some() =>
1684-
{
1682+
ty::Tuple(inputs) if infcx.tcx.is_fn_trait(trait_ref.def_id()) => {
16851683
infcx.tcx.mk_fn_sig(
16861684
inputs.iter(),
16871685
infcx.next_ty_var(TypeVariableOrigin {
@@ -1752,7 +1750,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
17521750
&& let predicates = self.tcx.predicates_of(def_id).instantiate_identity(self.tcx)
17531751
&& let Some(pred) = predicates.predicates.get(*idx)
17541752
&& let ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) = pred.kind().skip_binder()
1755-
&& ty::ClosureKind::from_def_id(self.tcx, trait_pred.def_id()).is_some()
1753+
&& self.tcx.is_fn_trait(trait_pred.def_id())
17561754
{
17571755
let expected_self =
17581756
self.tcx.anonymize_late_bound_regions(pred.kind().rebind(trait_pred.self_ty()));
@@ -1766,8 +1764,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
17661764
.enumerate()
17671765
.find(|(other_idx, (pred, _))| match pred.kind().skip_binder() {
17681766
ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred))
1769-
if ty::ClosureKind::from_def_id(self.tcx, trait_pred.def_id())
1770-
.is_some()
1767+
if self.tcx.is_fn_trait(trait_pred.def_id())
17711768
&& other_idx != idx
17721769
// Make sure that the self type matches
17731770
// (i.e. constraining this closure)

compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
451451
obligation: &TraitObligation<'tcx>,
452452
candidates: &mut SelectionCandidateSet<'tcx>,
453453
) {
454-
let Some(kind) = self.tcx().fn_trait_kind_from_lang_item(obligation.predicate.def_id()) else {
454+
let Some(kind) = self.tcx().fn_trait_kind_from_def_id(obligation.predicate.def_id()) else {
455455
return;
456456
};
457457

@@ -489,7 +489,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
489489
candidates: &mut SelectionCandidateSet<'tcx>,
490490
) {
491491
// We provide impl of all fn traits for fn pointers.
492-
if self.tcx().fn_trait_kind_from_lang_item(obligation.predicate.def_id()).is_none() {
492+
if !self.tcx().is_fn_trait(obligation.predicate.def_id()) {
493493
return;
494494
}
495495

compiler/rustc_trait_selection/src/traits/select/confirmation.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -735,7 +735,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
735735
) -> Result<ImplSourceClosureData<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>> {
736736
let kind = self
737737
.tcx()
738-
.fn_trait_kind_from_lang_item(obligation.predicate.def_id())
738+
.fn_trait_kind_from_def_id(obligation.predicate.def_id())
739739
.unwrap_or_else(|| bug!("closure candidate for non-fn trait {:?}", obligation));
740740

741741
// Okay to skip binder because the substs on closure types never

compiler/rustc_ty_utils/src/instance.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ fn resolve_associated_item<'tcx>(
209209
substs: future_data.substs,
210210
}),
211211
traits::ImplSource::Closure(closure_data) => {
212-
let trait_closure_kind = tcx.fn_trait_kind_from_lang_item(trait_id).unwrap();
212+
let trait_closure_kind = tcx.fn_trait_kind_from_def_id(trait_id).unwrap();
213213
Instance::resolve_closure(
214214
tcx,
215215
closure_data.closure_def_id,

src/librustdoc/clean/utils.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ fn external_generic_args<'tcx>(
106106
) -> GenericArgs {
107107
let args = substs_to_args(cx, substs, has_self);
108108

109-
if cx.tcx.fn_trait_kind_from_lang_item(did).is_some() {
109+
if cx.tcx.fn_trait_kind_from_def_id(did).is_some() {
110110
let inputs =
111111
// The trait's first substitution is the one after self, if there is one.
112112
match substs.iter().nth(if has_self { 1 } else { 0 }).unwrap().expect_ty().kind() {

0 commit comments

Comments
 (0)