Skip to content

Commit d97d4eb

Browse files
Remove even more redundant builtin candidates
1 parent 2835d9d commit d97d4eb

File tree

6 files changed

+96
-138
lines changed

6 files changed

+96
-138
lines changed

compiler/rustc_const_eval/src/transform/check_consts/check.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -781,7 +781,11 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
781781
);
782782
return;
783783
}
784-
Ok(Some(ImplSource::Closure(_))) => {
784+
// Closure: Fn{Once|Mut}
785+
Ok(Some(ImplSource::Builtin(_)))
786+
if poly_trait_pred.self_ty().skip_binder().is_closure()
787+
&& tcx.fn_trait_kind_from_def_id(trait_id).is_some() =>
788+
{
785789
let ty::Closure(closure_def_id, substs) =
786790
*poly_trait_pred.self_ty().no_bound_vars().unwrap().kind()
787791
else {

compiler/rustc_middle/src/traits/mod.rs

+3-36
Original file line numberDiff line numberDiff line change
@@ -661,20 +661,6 @@ pub enum ImplSource<'tcx, N> {
661661
/// ImplSource for trait upcasting coercion
662662
TraitUpcasting(ImplSourceTraitUpcastingData<N>),
663663

664-
/// ImplSource automatically generated for a closure. The `DefId` is the ID
665-
/// of the closure expression. This is an `ImplSource::UserDefined` in spirit, but the
666-
/// impl is generated by the compiler and does not appear in the source.
667-
Closure(Vec<N>),
668-
669-
/// Same as above, but for a function pointer type with the given signature.
670-
FnPointer(Vec<N>),
671-
672-
/// ImplSource automatically generated for a generator.
673-
Generator(Vec<N>),
674-
675-
/// ImplSource automatically generated for a generator backing an async future.
676-
Future(Vec<N>),
677-
678664
/// ImplSource for a trait alias.
679665
TraitAlias(ImplSourceTraitAliasData<'tcx, N>),
680666
}
@@ -683,12 +669,7 @@ impl<'tcx, N> ImplSource<'tcx, N> {
683669
pub fn nested_obligations(self) -> Vec<N> {
684670
match self {
685671
ImplSource::UserDefined(i) => i.nested,
686-
ImplSource::Param(n, _)
687-
| ImplSource::Builtin(n)
688-
| ImplSource::FnPointer(n)
689-
| ImplSource::Closure(n)
690-
| ImplSource::Generator(n)
691-
| ImplSource::Future(n) => n,
672+
ImplSource::Param(n, _) | ImplSource::Builtin(n) => n,
692673
ImplSource::Object(d) => d.nested,
693674
ImplSource::TraitAlias(d) => d.nested,
694675
ImplSource::TraitUpcasting(d) => d.nested,
@@ -698,12 +679,7 @@ impl<'tcx, N> ImplSource<'tcx, N> {
698679
pub fn borrow_nested_obligations(&self) -> &[N] {
699680
match self {
700681
ImplSource::UserDefined(i) => &i.nested,
701-
ImplSource::Param(n, _)
702-
| ImplSource::Builtin(n)
703-
| ImplSource::FnPointer(n)
704-
| ImplSource::Closure(n)
705-
| ImplSource::Generator(n)
706-
| ImplSource::Future(n) => &n,
682+
ImplSource::Param(n, _) | ImplSource::Builtin(n) => &n,
707683
ImplSource::Object(d) => &d.nested,
708684
ImplSource::TraitAlias(d) => &d.nested,
709685
ImplSource::TraitUpcasting(d) => &d.nested,
@@ -713,12 +689,7 @@ impl<'tcx, N> ImplSource<'tcx, N> {
713689
pub fn borrow_nested_obligations_mut(&mut self) -> &mut [N] {
714690
match self {
715691
ImplSource::UserDefined(i) => &mut i.nested,
716-
ImplSource::Param(n, _)
717-
| ImplSource::Builtin(n)
718-
| ImplSource::FnPointer(n)
719-
| ImplSource::Closure(n)
720-
| ImplSource::Generator(n)
721-
| ImplSource::Future(n) => n,
692+
ImplSource::Param(n, _) | ImplSource::Builtin(n) => n,
722693
ImplSource::Object(d) => &mut d.nested,
723694
ImplSource::TraitAlias(d) => &mut d.nested,
724695
ImplSource::TraitUpcasting(d) => &mut d.nested,
@@ -742,10 +713,6 @@ impl<'tcx, N> ImplSource<'tcx, N> {
742713
vtable_base: o.vtable_base,
743714
nested: o.nested.into_iter().map(f).collect(),
744715
}),
745-
ImplSource::Closure(n) => ImplSource::Closure(n.into_iter().map(f).collect()),
746-
ImplSource::Generator(n) => ImplSource::Generator(n.into_iter().map(f).collect()),
747-
ImplSource::Future(n) => ImplSource::Future(n.into_iter().map(f).collect()),
748-
ImplSource::FnPointer(n) => ImplSource::FnPointer(n.into_iter().map(f).collect()),
749716
ImplSource::TraitAlias(d) => ImplSource::TraitAlias(ImplSourceTraitAliasData {
750717
alias_def_id: d.alias_def_id,
751718
substs: d.substs,

compiler/rustc_middle/src/traits/structural_impls.rs

+1-9
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,14 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSource<'tcx, N> {
99
match *self {
1010
super::ImplSource::UserDefined(ref v) => write!(f, "{:?}", v),
1111

12-
super::ImplSource::Closure(ref d) => write!(f, "{:?}", d),
13-
14-
super::ImplSource::Generator(ref d) => write!(f, "{:?}", d),
15-
16-
super::ImplSource::Future(ref d) => write!(f, "{:?}", d),
17-
18-
super::ImplSource::FnPointer(ref d) => write!(f, "({:?})", d),
12+
super::ImplSource::Builtin(ref d) => write!(f, "{:?}", d),
1913

2014
super::ImplSource::Object(ref d) => write!(f, "{:?}", d),
2115

2216
super::ImplSource::Param(ref n, ct) => {
2317
write!(f, "ImplSourceParamData({:?}, {:?})", n, ct)
2418
}
2519

26-
super::ImplSource::Builtin(ref d) => write!(f, "{:?}", d),
27-
2820
super::ImplSource::TraitAlias(ref d) => write!(f, "{:?}", d),
2921

3022
super::ImplSource::TraitUpcasting(ref d) => write!(f, "{:?}", d),

compiler/rustc_trait_selection/src/traits/project.rs

+23-11
Original file line numberDiff line numberDiff line change
@@ -1717,11 +1717,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
17171717
};
17181718

17191719
let eligible = match &impl_source {
1720-
super::ImplSource::Closure(_)
1721-
| super::ImplSource::Generator(_)
1722-
| super::ImplSource::Future(_)
1723-
| super::ImplSource::FnPointer(_)
1724-
| super::ImplSource::TraitAlias(_) => true,
1720+
super::ImplSource::TraitAlias(_) => true,
17251721
super::ImplSource::UserDefined(impl_data) => {
17261722
// We have to be careful when projecting out of an
17271723
// impl because of specialization. If we are not in
@@ -1779,7 +1775,11 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
17791775
let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty());
17801776

17811777
let lang_items = selcx.tcx().lang_items();
1782-
if lang_items.discriminant_kind_trait() == Some(poly_trait_ref.def_id()) {
1778+
if [lang_items.gen_trait(), lang_items.future_trait()].contains(&Some(poly_trait_ref.def_id()))
1779+
|| selcx.tcx().fn_trait_kind_from_def_id(poly_trait_ref.def_id()).is_some()
1780+
{
1781+
true
1782+
} else if lang_items.discriminant_kind_trait() == Some(poly_trait_ref.def_id()) {
17831783
match self_ty.kind() {
17841784
ty::Bool
17851785
| ty::Char
@@ -1990,11 +1990,23 @@ fn confirm_select_candidate<'cx, 'tcx>(
19901990
) -> Progress<'tcx> {
19911991
match impl_source {
19921992
super::ImplSource::UserDefined(data) => confirm_impl_candidate(selcx, obligation, data),
1993-
super::ImplSource::Generator(data) => confirm_generator_candidate(selcx, obligation, data),
1994-
super::ImplSource::Future(data) => confirm_future_candidate(selcx, obligation, data),
1995-
super::ImplSource::Closure(data) => confirm_closure_candidate(selcx, obligation, data),
1996-
super::ImplSource::FnPointer(data) => confirm_fn_pointer_candidate(selcx, obligation, data),
1997-
super::ImplSource::Builtin(data) => confirm_builtin_candidate(selcx, obligation, data),
1993+
super::ImplSource::Builtin(data) => {
1994+
let trait_def_id = obligation.predicate.trait_def_id(selcx.tcx());
1995+
let lang_items = selcx.tcx().lang_items();
1996+
if lang_items.gen_trait() == Some(trait_def_id) {
1997+
confirm_generator_candidate(selcx, obligation, data)
1998+
} else if lang_items.future_trait() == Some(trait_def_id) {
1999+
confirm_future_candidate(selcx, obligation, data)
2000+
} else if selcx.tcx().fn_trait_kind_from_def_id(trait_def_id).is_some() {
2001+
if obligation.predicate.self_ty().is_closure() {
2002+
confirm_closure_candidate(selcx, obligation, data)
2003+
} else {
2004+
confirm_fn_pointer_candidate(selcx, obligation, data)
2005+
}
2006+
} else {
2007+
confirm_builtin_candidate(selcx, obligation, data)
2008+
}
2009+
}
19982010
super::ImplSource::Object(_)
19992011
| super::ImplSource::Param(..)
20002012
| super::ImplSource::TraitUpcasting(_)

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -85,22 +85,22 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
8585

8686
ClosureCandidate { .. } => {
8787
let vtable_closure = self.confirm_closure_candidate(obligation)?;
88-
ImplSource::Closure(vtable_closure)
88+
ImplSource::Builtin(vtable_closure)
8989
}
9090

9191
GeneratorCandidate => {
9292
let vtable_generator = self.confirm_generator_candidate(obligation)?;
93-
ImplSource::Generator(vtable_generator)
93+
ImplSource::Builtin(vtable_generator)
9494
}
9595

9696
FutureCandidate => {
9797
let vtable_future = self.confirm_future_candidate(obligation)?;
98-
ImplSource::Future(vtable_future)
98+
ImplSource::Builtin(vtable_future)
9999
}
100100

101101
FnPointerCandidate { is_const } => {
102102
let data = self.confirm_fn_pointer_candidate(obligation, is_const)?;
103-
ImplSource::FnPointer(data)
103+
ImplSource::Builtin(data)
104104
}
105105

106106
TraitAliasCandidate => {

compiler/rustc_ty_utils/src/instance.rs

+60-77
Original file line numberDiff line numberDiff line change
@@ -177,83 +177,6 @@ fn resolve_associated_item<'tcx>(
177177

178178
Some(ty::Instance::new(leaf_def.item.def_id, substs))
179179
}
180-
traits::ImplSource::Generator(_) => {
181-
let ty::Generator(generator_def_id, substs, _) = *rcvr_substs.type_at(0).kind() else {
182-
unreachable!()
183-
};
184-
if cfg!(debug_assertions) && tcx.item_name(trait_item_id) != sym::resume {
185-
// For compiler developers who'd like to add new items to `Generator`,
186-
// you either need to generate a shim body, or perhaps return
187-
// `InstanceDef::Item` pointing to a trait default method body if
188-
// it is given a default implementation by the trait.
189-
span_bug!(
190-
tcx.def_span(generator_def_id),
191-
"no definition for `{trait_ref}::{}` for built-in generator type",
192-
tcx.item_name(trait_item_id)
193-
)
194-
}
195-
Some(Instance { def: ty::InstanceDef::Item(generator_def_id), substs })
196-
}
197-
traits::ImplSource::Future(_) => {
198-
let ty::Generator(generator_def_id, substs, _) = *rcvr_substs.type_at(0).kind() else {
199-
unreachable!()
200-
};
201-
if Some(trait_item_id) == tcx.lang_items().future_poll_fn() {
202-
// `Future::poll` is generated by the compiler.
203-
Some(Instance { def: ty::InstanceDef::Item(generator_def_id), substs: substs })
204-
} else {
205-
// All other methods are default methods of the `Future` trait.
206-
// (this assumes that `ImplSource::Future` is only used for methods on `Future`)
207-
debug_assert!(tcx.defaultness(trait_item_id).has_value());
208-
Some(Instance::new(trait_item_id, rcvr_substs))
209-
}
210-
}
211-
traits::ImplSource::Closure(_) => {
212-
let ty::Closure(closure_def_id, substs) = *rcvr_substs.type_at(0).kind() else {
213-
unreachable!()
214-
};
215-
if cfg!(debug_assertions)
216-
&& ![sym::call, sym::call_mut, sym::call_once]
217-
.contains(&tcx.item_name(trait_item_id))
218-
{
219-
// For compiler developers who'd like to add new items to `Fn`/`FnMut`/`FnOnce`,
220-
// you either need to generate a shim body, or perhaps return
221-
// `InstanceDef::Item` pointing to a trait default method body if
222-
// it is given a default implementation by the trait.
223-
span_bug!(
224-
tcx.def_span(closure_def_id),
225-
"no definition for `{trait_ref}::{}` for built-in closure type",
226-
tcx.item_name(trait_item_id)
227-
)
228-
}
229-
let trait_closure_kind = tcx.fn_trait_kind_from_def_id(trait_id).unwrap();
230-
Instance::resolve_closure(tcx, closure_def_id, substs, trait_closure_kind)
231-
}
232-
traits::ImplSource::FnPointer(_) => match rcvr_substs.type_at(0).kind() {
233-
ty::FnDef(..) | ty::FnPtr(..) => {
234-
if cfg!(debug_assertions)
235-
&& ![sym::call, sym::call_mut, sym::call_once]
236-
.contains(&tcx.item_name(trait_item_id))
237-
{
238-
// For compiler developers who'd like to add new items to `Fn`/`FnMut`/`FnOnce`,
239-
// you either need to generate a shim body, or perhaps return
240-
// `InstanceDef::Item` pointing to a trait default method body if
241-
// it is given a default implementation by the trait.
242-
bug!(
243-
"no definition for `{trait_ref}::{}` for built-in fn type",
244-
tcx.item_name(trait_item_id)
245-
)
246-
}
247-
Some(Instance {
248-
def: ty::InstanceDef::FnPtrShim(trait_item_id, rcvr_substs.type_at(0)),
249-
substs: rcvr_substs,
250-
})
251-
}
252-
_ => bug!(
253-
"no built-in definition for `{trait_ref}::{}` for non-fn type",
254-
tcx.item_name(trait_item_id)
255-
),
256-
},
257180
traits::ImplSource::Object(ref data) => {
258181
traits::get_vtable_index_of_object_method(tcx, data, trait_item_id).map(|index| {
259182
Instance {
@@ -306,6 +229,66 @@ fn resolve_associated_item<'tcx>(
306229
span: tcx.def_span(trait_item_id),
307230
})
308231
}
232+
} else if Some(trait_ref.def_id) == lang_items.future_trait() {
233+
let ty::Generator(generator_def_id, substs, _) = *rcvr_substs.type_at(0).kind() else {
234+
bug!()
235+
};
236+
if Some(trait_item_id) == tcx.lang_items().future_poll_fn() {
237+
// `Future::poll` is generated by the compiler.
238+
Some(Instance { def: ty::InstanceDef::Item(generator_def_id), substs: substs })
239+
} else {
240+
// All other methods are default methods of the `Future` trait.
241+
// (this assumes that `ImplSource::Builtin` is only used for methods on `Future`)
242+
debug_assert!(tcx.defaultness(trait_item_id).has_value());
243+
Some(Instance::new(trait_item_id, rcvr_substs))
244+
}
245+
} else if Some(trait_ref.def_id) == lang_items.gen_trait() {
246+
let ty::Generator(generator_def_id, substs, _) = *rcvr_substs.type_at(0).kind() else {
247+
bug!()
248+
};
249+
if cfg!(debug_assertions) && tcx.item_name(trait_item_id) != sym::resume {
250+
// For compiler developers who'd like to add new items to `Generator`,
251+
// you either need to generate a shim body, or perhaps return
252+
// `InstanceDef::Item` pointing to a trait default method body if
253+
// it is given a default implementation by the trait.
254+
span_bug!(
255+
tcx.def_span(generator_def_id),
256+
"no definition for `{trait_ref}::{}` for built-in generator type",
257+
tcx.item_name(trait_item_id)
258+
)
259+
}
260+
Some(Instance { def: ty::InstanceDef::Item(generator_def_id), substs })
261+
} else if tcx.fn_trait_kind_from_def_id(trait_ref.def_id).is_some() {
262+
// FIXME: This doesn't check for malformed libcore that defines, e.g.,
263+
// `trait Fn { fn call_once(&self) { .. } }`. This is mostly for extension
264+
// methods.
265+
if cfg!(debug_assertions)
266+
&& ![sym::call, sym::call_mut, sym::call_once]
267+
.contains(&tcx.item_name(trait_item_id))
268+
{
269+
// For compiler developers who'd like to add new items to `Fn`/`FnMut`/`FnOnce`,
270+
// you either need to generate a shim body, or perhaps return
271+
// `InstanceDef::Item` pointing to a trait default method body if
272+
// it is given a default implementation by the trait.
273+
bug!(
274+
"no definition for `{trait_ref}::{}` for built-in callable type",
275+
tcx.item_name(trait_item_id)
276+
)
277+
}
278+
match *rcvr_substs.type_at(0).kind() {
279+
ty::Closure(closure_def_id, substs) => {
280+
let trait_closure_kind = tcx.fn_trait_kind_from_def_id(trait_id).unwrap();
281+
Instance::resolve_closure(tcx, closure_def_id, substs, trait_closure_kind)
282+
}
283+
ty::FnDef(..) | ty::FnPtr(..) => Some(Instance {
284+
def: ty::InstanceDef::FnPtrShim(trait_item_id, rcvr_substs.type_at(0)),
285+
substs: rcvr_substs,
286+
}),
287+
_ => bug!(
288+
"no built-in definition for `{trait_ref}::{}` for non-fn type",
289+
tcx.item_name(trait_item_id)
290+
),
291+
}
309292
} else {
310293
None
311294
}

0 commit comments

Comments
 (0)