summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_ty_utils/src/instance.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_ty_utils/src/instance.rs')
-rw-r--r--compiler/rustc_ty_utils/src/instance.rs147
1 files changed, 62 insertions, 85 deletions
diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs
index 36a20c78f..1d93a79e5 100644
--- a/compiler/rustc_ty_utils/src/instance.rs
+++ b/compiler/rustc_ty_utils/src/instance.rs
@@ -80,7 +80,7 @@ fn resolve_associated_item<'tcx>(
let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_substs);
- let vtbl = match tcx.codegen_select_candidate((param_env, ty::Binder::dummy(trait_ref))) {
+ let vtbl = match tcx.codegen_select_candidate((param_env, trait_ref)) {
Ok(vtbl) => vtbl,
Err(CodegenObligationError::Ambiguity) => {
let reported = tcx.sess.delay_span_bug(
@@ -177,85 +177,6 @@ fn resolve_associated_item<'tcx>(
Some(ty::Instance::new(leaf_def.item.def_id, substs))
}
- traits::ImplSource::Generator(generator_data) => {
- if cfg!(debug_assertions) && tcx.item_name(trait_item_id) != sym::resume {
- // For compiler developers who'd like to add new items to `Generator`,
- // you either need to generate a shim body, or perhaps return
- // `InstanceDef::Item` pointing to a trait default method body if
- // it is given a default implementation by the trait.
- span_bug!(
- tcx.def_span(generator_data.generator_def_id),
- "no definition for `{trait_ref}::{}` for built-in generator type",
- tcx.item_name(trait_item_id)
- )
- }
- Some(Instance {
- def: ty::InstanceDef::Item(generator_data.generator_def_id),
- substs: generator_data.substs,
- })
- }
- traits::ImplSource::Future(future_data) => {
- if Some(trait_item_id) == tcx.lang_items().future_poll_fn() {
- // `Future::poll` is generated by the compiler.
- Some(Instance {
- def: ty::InstanceDef::Item(future_data.generator_def_id),
- substs: future_data.substs,
- })
- } else {
- // All other methods are default methods of the `Future` trait.
- // (this assumes that `ImplSource::Future` is only used for methods on `Future`)
- debug_assert!(tcx.impl_defaultness(trait_item_id).has_value());
- Some(Instance::new(trait_item_id, rcvr_substs))
- }
- }
- traits::ImplSource::Closure(closure_data) => {
- if cfg!(debug_assertions)
- && ![sym::call, sym::call_mut, sym::call_once]
- .contains(&tcx.item_name(trait_item_id))
- {
- // For compiler developers who'd like to add new items to `Fn`/`FnMut`/`FnOnce`,
- // you either need to generate a shim body, or perhaps return
- // `InstanceDef::Item` pointing to a trait default method body if
- // it is given a default implementation by the trait.
- span_bug!(
- tcx.def_span(closure_data.closure_def_id),
- "no definition for `{trait_ref}::{}` for built-in closure type",
- tcx.item_name(trait_item_id)
- )
- }
- let trait_closure_kind = tcx.fn_trait_kind_from_def_id(trait_id).unwrap();
- Instance::resolve_closure(
- tcx,
- closure_data.closure_def_id,
- closure_data.substs,
- trait_closure_kind,
- )
- }
- traits::ImplSource::FnPointer(ref data) => match data.fn_ty.kind() {
- ty::FnDef(..) | ty::FnPtr(..) => {
- if cfg!(debug_assertions)
- && ![sym::call, sym::call_mut, sym::call_once]
- .contains(&tcx.item_name(trait_item_id))
- {
- // For compiler developers who'd like to add new items to `Fn`/`FnMut`/`FnOnce`,
- // you either need to generate a shim body, or perhaps return
- // `InstanceDef::Item` pointing to a trait default method body if
- // it is given a default implementation by the trait.
- bug!(
- "no definition for `{trait_ref}::{}` for built-in fn type",
- tcx.item_name(trait_item_id)
- )
- }
- Some(Instance {
- def: ty::InstanceDef::FnPtrShim(trait_item_id, data.fn_ty),
- substs: rcvr_substs,
- })
- }
- _ => bug!(
- "no built-in definition for `{trait_ref}::{}` for non-fn type",
- tcx.item_name(trait_item_id)
- ),
- },
traits::ImplSource::Object(ref data) => {
traits::get_vtable_index_of_object_method(tcx, data, trait_item_id).map(|index| {
Instance {
@@ -308,15 +229,71 @@ fn resolve_associated_item<'tcx>(
span: tcx.def_span(trait_item_id),
})
}
+ } else if Some(trait_ref.def_id) == lang_items.future_trait() {
+ let ty::Generator(generator_def_id, substs, _) = *rcvr_substs.type_at(0).kind() else {
+ bug!()
+ };
+ if Some(trait_item_id) == tcx.lang_items().future_poll_fn() {
+ // `Future::poll` is generated by the compiler.
+ Some(Instance { def: ty::InstanceDef::Item(generator_def_id), substs: substs })
+ } else {
+ // All other methods are default methods of the `Future` trait.
+ // (this assumes that `ImplSource::Builtin` is only used for methods on `Future`)
+ debug_assert!(tcx.defaultness(trait_item_id).has_value());
+ Some(Instance::new(trait_item_id, rcvr_substs))
+ }
+ } else if Some(trait_ref.def_id) == lang_items.gen_trait() {
+ let ty::Generator(generator_def_id, substs, _) = *rcvr_substs.type_at(0).kind() else {
+ bug!()
+ };
+ if cfg!(debug_assertions) && tcx.item_name(trait_item_id) != sym::resume {
+ // For compiler developers who'd like to add new items to `Generator`,
+ // you either need to generate a shim body, or perhaps return
+ // `InstanceDef::Item` pointing to a trait default method body if
+ // it is given a default implementation by the trait.
+ span_bug!(
+ tcx.def_span(generator_def_id),
+ "no definition for `{trait_ref}::{}` for built-in generator type",
+ tcx.item_name(trait_item_id)
+ )
+ }
+ Some(Instance { def: ty::InstanceDef::Item(generator_def_id), substs })
+ } else if tcx.fn_trait_kind_from_def_id(trait_ref.def_id).is_some() {
+ // FIXME: This doesn't check for malformed libcore that defines, e.g.,
+ // `trait Fn { fn call_once(&self) { .. } }`. This is mostly for extension
+ // methods.
+ if cfg!(debug_assertions)
+ && ![sym::call, sym::call_mut, sym::call_once]
+ .contains(&tcx.item_name(trait_item_id))
+ {
+ // For compiler developers who'd like to add new items to `Fn`/`FnMut`/`FnOnce`,
+ // you either need to generate a shim body, or perhaps return
+ // `InstanceDef::Item` pointing to a trait default method body if
+ // it is given a default implementation by the trait.
+ bug!(
+ "no definition for `{trait_ref}::{}` for built-in callable type",
+ tcx.item_name(trait_item_id)
+ )
+ }
+ match *rcvr_substs.type_at(0).kind() {
+ ty::Closure(closure_def_id, substs) => {
+ let trait_closure_kind = tcx.fn_trait_kind_from_def_id(trait_id).unwrap();
+ Instance::resolve_closure(tcx, closure_def_id, substs, trait_closure_kind)
+ }
+ ty::FnDef(..) | ty::FnPtr(..) => Some(Instance {
+ def: ty::InstanceDef::FnPtrShim(trait_item_id, rcvr_substs.type_at(0)),
+ substs: rcvr_substs,
+ }),
+ _ => bug!(
+ "no built-in definition for `{trait_ref}::{}` for non-fn type",
+ tcx.item_name(trait_item_id)
+ ),
+ }
} else {
None
}
}
- traits::ImplSource::AutoImpl(..)
- | traits::ImplSource::Param(..)
- | traits::ImplSource::TraitAlias(..)
- | traits::ImplSource::TraitUpcasting(_)
- | traits::ImplSource::ConstDestruct(_) => None,
+ traits::ImplSource::Param(..) | traits::ImplSource::TraitUpcasting(_) => None,
})
}