Consolidate logic around resolving built-in coroutine trait impls
This commit is contained in:
parent
32ec40c685
commit
f2ef88ba06
5 changed files with 56 additions and 58 deletions
|
@ -245,63 +245,6 @@ 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::Coroutine(coroutine_def_id, args) = *rcvr_args.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(coroutine_def_id), args: args })
|
||||
} 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_args))
|
||||
}
|
||||
} else if Some(trait_ref.def_id) == lang_items.iterator_trait() {
|
||||
let ty::Coroutine(coroutine_def_id, args) = *rcvr_args.type_at(0).kind() else {
|
||||
bug!()
|
||||
};
|
||||
if Some(trait_item_id) == tcx.lang_items().next_fn() {
|
||||
// `Iterator::next` is generated by the compiler.
|
||||
Some(Instance { def: ty::InstanceDef::Item(coroutine_def_id), args })
|
||||
} else {
|
||||
// All other methods are default methods of the `Iterator` trait.
|
||||
// (this assumes that `ImplSource::Builtin` is only used for methods on `Iterator`)
|
||||
debug_assert!(tcx.defaultness(trait_item_id).has_value());
|
||||
Some(Instance::new(trait_item_id, rcvr_args))
|
||||
}
|
||||
} else if Some(trait_ref.def_id) == lang_items.async_iterator_trait() {
|
||||
let ty::Coroutine(coroutine_def_id, args) = *rcvr_args.type_at(0).kind() else {
|
||||
bug!()
|
||||
};
|
||||
|
||||
if cfg!(debug_assertions) && tcx.item_name(trait_item_id) != sym::poll_next {
|
||||
span_bug!(
|
||||
tcx.def_span(coroutine_def_id),
|
||||
"no definition for `{trait_ref}::{}` for built-in coroutine type",
|
||||
tcx.item_name(trait_item_id)
|
||||
)
|
||||
}
|
||||
|
||||
// `AsyncIterator::poll_next` is generated by the compiler.
|
||||
Some(Instance { def: ty::InstanceDef::Item(coroutine_def_id), args })
|
||||
} else if Some(trait_ref.def_id) == lang_items.coroutine_trait() {
|
||||
let ty::Coroutine(coroutine_def_id, args) = *rcvr_args.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 `Coroutine`,
|
||||
// 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(coroutine_def_id),
|
||||
"no definition for `{trait_ref}::{}` for built-in coroutine type",
|
||||
tcx.item_name(trait_item_id)
|
||||
)
|
||||
}
|
||||
Some(Instance { def: ty::InstanceDef::Item(coroutine_def_id), args })
|
||||
} 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
|
||||
|
@ -334,7 +277,7 @@ fn resolve_associated_item<'tcx>(
|
|||
),
|
||||
}
|
||||
} else {
|
||||
None
|
||||
Instance::try_resolve_item_for_coroutine(tcx, trait_item_id, trait_id, rcvr_args)
|
||||
}
|
||||
}
|
||||
traits::ImplSource::Param(..)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue