Skip to content

Commit 4ef08a1

Browse files
committed
Auto merge of rust-lang#140386 - oli-obk:match-on-lang-item-kind, r=<try>
Match on lang item kind instead of using an if/else chain r? `@ghost`
2 parents 0134651 + 7454d4c commit 4ef08a1

File tree

1 file changed

+97
-78
lines changed

1 file changed

+97
-78
lines changed

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

+97-78
Original file line numberDiff line numberDiff line change
@@ -66,74 +66,103 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
6666
let def_id = obligation.predicate.def_id();
6767
let tcx = self.tcx();
6868

69-
if tcx.is_lang_item(def_id, LangItem::Copy) {
70-
debug!(obligation_self_ty = ?obligation.predicate.skip_binder().self_ty());
71-
72-
// User-defined copy impls are permitted, but only for
73-
// structs and enums.
74-
self.assemble_candidates_from_impls(obligation, &mut candidates);
75-
76-
// For other types, we'll use the builtin rules.
77-
let copy_conditions = self.copy_clone_conditions(obligation);
78-
self.assemble_builtin_bound_candidates(copy_conditions, &mut candidates);
79-
} else if tcx.is_lang_item(def_id, LangItem::DiscriminantKind) {
80-
// `DiscriminantKind` is automatically implemented for every type.
81-
candidates.vec.push(BuiltinCandidate { has_nested: false });
82-
} else if tcx.is_lang_item(def_id, LangItem::AsyncDestruct) {
83-
// `AsyncDestruct` is automatically implemented for every type.
84-
candidates.vec.push(BuiltinCandidate { has_nested: false });
85-
} else if tcx.is_lang_item(def_id, LangItem::PointeeTrait) {
86-
// `Pointee` is automatically implemented for every type.
87-
candidates.vec.push(BuiltinCandidate { has_nested: false });
88-
} else if tcx.is_lang_item(def_id, LangItem::Sized) {
89-
self.assemble_builtin_sized_candidate(obligation, &mut candidates);
90-
} else if tcx.is_lang_item(def_id, LangItem::Unsize) {
91-
self.assemble_candidates_for_unsizing(obligation, &mut candidates);
92-
} else if tcx.is_lang_item(def_id, LangItem::Destruct) {
93-
self.assemble_const_destruct_candidates(obligation, &mut candidates);
94-
} else if tcx.is_lang_item(def_id, LangItem::TransmuteTrait) {
95-
// User-defined transmutability impls are permitted.
96-
self.assemble_candidates_from_impls(obligation, &mut candidates);
97-
self.assemble_candidates_for_transmutability(obligation, &mut candidates);
98-
} else if tcx.is_lang_item(def_id, LangItem::Tuple) {
99-
self.assemble_candidate_for_tuple(obligation, &mut candidates);
100-
} else if tcx.is_lang_item(def_id, LangItem::FnPtrTrait) {
101-
self.assemble_candidates_for_fn_ptr_trait(obligation, &mut candidates);
102-
} else if tcx.is_lang_item(def_id, LangItem::BikeshedGuaranteedNoDrop) {
103-
self.assemble_candidates_for_bikeshed_guaranteed_no_drop_trait(
104-
obligation,
105-
&mut candidates,
106-
);
107-
} else {
108-
if tcx.is_lang_item(def_id, LangItem::Clone) {
109-
// Same builtin conditions as `Copy`, i.e., every type which has builtin support
110-
// for `Copy` also has builtin support for `Clone`, and tuples/arrays of `Clone`
111-
// types have builtin support for `Clone`.
112-
let clone_conditions = self.copy_clone_conditions(obligation);
113-
self.assemble_builtin_bound_candidates(clone_conditions, &mut candidates);
69+
let lang_item = tcx.as_lang_item(def_id);
70+
match lang_item {
71+
Some(LangItem::Copy) => {
72+
debug!(obligation_self_ty = ?obligation.predicate.skip_binder().self_ty());
73+
74+
// User-defined copy impls are permitted, but only for
75+
// structs and enums.
76+
self.assemble_candidates_from_impls(obligation, &mut candidates);
77+
78+
// For other types, we'll use the builtin rules.
79+
let copy_conditions = self.copy_clone_conditions(obligation);
80+
self.assemble_builtin_bound_candidates(copy_conditions, &mut candidates);
11481
}
115-
116-
if tcx.is_lang_item(def_id, LangItem::Coroutine) {
117-
self.assemble_coroutine_candidates(obligation, &mut candidates);
118-
} else if tcx.is_lang_item(def_id, LangItem::Future) {
119-
self.assemble_future_candidates(obligation, &mut candidates);
120-
} else if tcx.is_lang_item(def_id, LangItem::Iterator) {
121-
self.assemble_iterator_candidates(obligation, &mut candidates);
122-
} else if tcx.is_lang_item(def_id, LangItem::FusedIterator) {
123-
self.assemble_fused_iterator_candidates(obligation, &mut candidates);
124-
} else if tcx.is_lang_item(def_id, LangItem::AsyncIterator) {
125-
self.assemble_async_iterator_candidates(obligation, &mut candidates);
126-
} else if tcx.is_lang_item(def_id, LangItem::AsyncFnKindHelper) {
127-
self.assemble_async_fn_kind_helper_candidates(obligation, &mut candidates);
82+
Some(LangItem::DiscriminantKind) => {
83+
// `DiscriminantKind` is automatically implemented for every type.
84+
candidates.vec.push(BuiltinCandidate { has_nested: false });
12885
}
86+
Some(LangItem::AsyncDestruct) => {
87+
// `AsyncDestruct` is automatically implemented for every type.
88+
candidates.vec.push(BuiltinCandidate { has_nested: false });
89+
}
90+
Some(LangItem::PointeeTrait) => {
91+
// `Pointee` is automatically implemented for every type.
92+
candidates.vec.push(BuiltinCandidate { has_nested: false });
93+
}
94+
Some(LangItem::Sized) => {
95+
self.assemble_builtin_sized_candidate(obligation, &mut candidates);
96+
}
97+
Some(LangItem::Unsize) => {
98+
self.assemble_candidates_for_unsizing(obligation, &mut candidates);
99+
}
100+
Some(LangItem::Destruct) => {
101+
self.assemble_const_destruct_candidates(obligation, &mut candidates);
102+
}
103+
Some(LangItem::TransmuteTrait) => {
104+
// User-defined transmutability impls are permitted.
105+
self.assemble_candidates_from_impls(obligation, &mut candidates);
106+
self.assemble_candidates_for_transmutability(obligation, &mut candidates);
107+
}
108+
Some(LangItem::Tuple) => {
109+
self.assemble_candidate_for_tuple(obligation, &mut candidates);
110+
}
111+
Some(LangItem::FnPtrTrait) => {
112+
self.assemble_candidates_for_fn_ptr_trait(obligation, &mut candidates);
113+
}
114+
Some(LangItem::BikeshedGuaranteedNoDrop) => {
115+
self.assemble_candidates_for_bikeshed_guaranteed_no_drop_trait(
116+
obligation,
117+
&mut candidates,
118+
);
119+
}
120+
_ => {
121+
match lang_item {
122+
Some(LangItem::Clone) => {
123+
// Same builtin conditions as `Copy`, i.e., every type which has builtin support
124+
// for `Copy` also has builtin support for `Clone`, and tuples/arrays of `Clone`
125+
// types have builtin support for `Clone`.
126+
let clone_conditions = self.copy_clone_conditions(obligation);
127+
self.assemble_builtin_bound_candidates(
128+
clone_conditions,
129+
&mut candidates,
130+
);
131+
}
132+
Some(LangItem::Coroutine) => {
133+
self.assemble_coroutine_candidates(obligation, &mut candidates);
134+
}
135+
Some(LangItem::Future) => {
136+
self.assemble_future_candidates(obligation, &mut candidates);
137+
}
138+
Some(LangItem::Iterator) => {
139+
self.assemble_iterator_candidates(obligation, &mut candidates);
140+
}
141+
Some(LangItem::FusedIterator) => {
142+
self.assemble_fused_iterator_candidates(obligation, &mut candidates);
143+
}
144+
Some(LangItem::AsyncIterator) => {
145+
self.assemble_async_iterator_candidates(obligation, &mut candidates);
146+
}
147+
Some(LangItem::AsyncFnKindHelper) => {
148+
self.assemble_async_fn_kind_helper_candidates(
149+
obligation,
150+
&mut candidates,
151+
);
152+
}
153+
Some(LangItem::AsyncFn | LangItem::AsyncFnMut | LangItem::AsyncFnOnce) => {
154+
self.assemble_async_closure_candidates(obligation, &mut candidates);
155+
}
156+
Some(LangItem::Fn | LangItem::FnMut | LangItem::FnOnce) => {
157+
self.assemble_closure_candidates(obligation, &mut candidates);
158+
self.assemble_fn_pointer_candidates(obligation, &mut candidates);
159+
}
160+
_ => {}
161+
}
129162

130-
// FIXME: Put these into `else if` blocks above, since they're built-in.
131-
self.assemble_closure_candidates(obligation, &mut candidates);
132-
self.assemble_async_closure_candidates(obligation, &mut candidates);
133-
self.assemble_fn_pointer_candidates(obligation, &mut candidates);
134-
135-
self.assemble_candidates_from_impls(obligation, &mut candidates);
136-
self.assemble_candidates_from_object_ty(obligation, &mut candidates);
163+
self.assemble_candidates_from_impls(obligation, &mut candidates);
164+
self.assemble_candidates_from_object_ty(obligation, &mut candidates);
165+
}
137166
}
138167

139168
self.assemble_candidates_from_projected_tys(obligation, &mut candidates);
@@ -364,9 +393,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
364393
obligation: &PolyTraitObligation<'tcx>,
365394
candidates: &mut SelectionCandidateSet<'tcx>,
366395
) {
367-
let Some(kind) = self.tcx().fn_trait_kind_from_def_id(obligation.predicate.def_id()) else {
368-
return;
369-
};
396+
let kind = self.tcx().fn_trait_kind_from_def_id(obligation.predicate.def_id()).unwrap();
370397

371398
// Okay to skip binder because the args on closure types never
372399
// touch bound regions, they just capture the in-scope
@@ -428,11 +455,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
428455
obligation: &PolyTraitObligation<'tcx>,
429456
candidates: &mut SelectionCandidateSet<'tcx>,
430457
) {
431-
let Some(goal_kind) =
432-
self.tcx().async_fn_trait_kind_from_def_id(obligation.predicate.def_id())
433-
else {
434-
return;
435-
};
458+
let goal_kind =
459+
self.tcx().async_fn_trait_kind_from_def_id(obligation.predicate.def_id()).unwrap();
436460

437461
match *obligation.self_ty().skip_binder().kind() {
438462
ty::CoroutineClosure(_, args) => {
@@ -505,11 +529,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
505529
obligation: &PolyTraitObligation<'tcx>,
506530
candidates: &mut SelectionCandidateSet<'tcx>,
507531
) {
508-
// We provide impl of all fn traits for fn pointers.
509-
if !self.tcx().is_fn_trait(obligation.predicate.def_id()) {
510-
return;
511-
}
512-
513532
// Keep this function in sync with extract_tupled_inputs_and_output_from_callable
514533
// until the old solver (and thus this function) is removed.
515534

0 commit comments

Comments
 (0)