Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 356f2d0

Browse files
committed
Auto merge of #140386 - oli-obk:match-on-lang-item-kind, r=compiler-errors
Match on lang item kind instead of using an if/else chain Similar to how the new solver does this. Just noticed while I was adding a new entry to the chain 😆
2 parents c43786c + 03c05c9 commit 356f2d0

File tree

2 files changed

+91
-85
lines changed

2 files changed

+91
-85
lines changed

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

Lines changed: 86 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -65,71 +65,92 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
6565
let def_id = obligation.predicate.def_id();
6666
let tcx = self.tcx();
6767

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

126-
// FIXME: Put these into `else if` blocks above, since they're built-in.
127-
self.assemble_closure_candidates(obligation, &mut candidates);
128-
self.assemble_async_closure_candidates(obligation, &mut candidates);
129-
self.assemble_fn_pointer_candidates(obligation, &mut candidates);
130-
131-
self.assemble_candidates_from_impls(obligation, &mut candidates);
132-
self.assemble_candidates_from_object_ty(obligation, &mut candidates);
151+
self.assemble_candidates_from_impls(obligation, &mut candidates);
152+
self.assemble_candidates_from_object_ty(obligation, &mut candidates);
153+
}
133154
}
134155

135156
self.assemble_candidates_from_projected_tys(obligation, &mut candidates);
@@ -360,9 +381,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
360381
obligation: &PolyTraitObligation<'tcx>,
361382
candidates: &mut SelectionCandidateSet<'tcx>,
362383
) {
363-
let Some(kind) = self.tcx().fn_trait_kind_from_def_id(obligation.predicate.def_id()) else {
364-
return;
365-
};
384+
let kind = self.tcx().fn_trait_kind_from_def_id(obligation.predicate.def_id()).unwrap();
366385

367386
// Okay to skip binder because the args on closure types never
368387
// touch bound regions, they just capture the in-scope
@@ -424,11 +443,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
424443
obligation: &PolyTraitObligation<'tcx>,
425444
candidates: &mut SelectionCandidateSet<'tcx>,
426445
) {
427-
let Some(goal_kind) =
428-
self.tcx().async_fn_trait_kind_from_def_id(obligation.predicate.def_id())
429-
else {
430-
return;
431-
};
446+
let goal_kind =
447+
self.tcx().async_fn_trait_kind_from_def_id(obligation.predicate.def_id()).unwrap();
432448

433449
match *obligation.self_ty().skip_binder().kind() {
434450
ty::CoroutineClosure(_, args) => {
@@ -501,11 +517,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
501517
obligation: &PolyTraitObligation<'tcx>,
502518
candidates: &mut SelectionCandidateSet<'tcx>,
503519
) {
504-
// We provide impl of all fn traits for fn pointers.
505-
if !self.tcx().is_fn_trait(obligation.predicate.def_id()) {
506-
return;
507-
}
508-
509520
// Keep this function in sync with extract_tupled_inputs_and_output_from_callable
510521
// until the old solver (and thus this function) is removed.
511522

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

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -251,16 +251,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
251251
let tcx = self.tcx();
252252
let obligations = if has_nested {
253253
let trait_def = obligation.predicate.def_id();
254-
let conditions = if tcx.is_lang_item(trait_def, LangItem::Sized) {
255-
self.sized_conditions(obligation)
256-
} else if tcx.is_lang_item(trait_def, LangItem::Copy) {
257-
self.copy_clone_conditions(obligation)
258-
} else if tcx.is_lang_item(trait_def, LangItem::Clone) {
259-
self.copy_clone_conditions(obligation)
260-
} else if tcx.is_lang_item(trait_def, LangItem::FusedIterator) {
261-
self.fused_iterator_conditions(obligation)
262-
} else {
263-
bug!("unexpected builtin trait {:?}", trait_def)
254+
let conditions = match tcx.as_lang_item(trait_def) {
255+
Some(LangItem::Sized) => self.sized_conditions(obligation),
256+
Some(LangItem::Copy | LangItem::Clone) => self.copy_clone_conditions(obligation),
257+
Some(LangItem::FusedIterator) => self.fused_iterator_conditions(obligation),
258+
other => bug!("unexpected builtin trait {trait_def:?} ({other:?})"),
264259
};
265260
let BuiltinImplConditions::Where(types) = conditions else {
266261
bug!("obligation {:?} had matched a builtin impl but now doesn't", obligation);

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /