mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 07:14:28 +00:00
Allow defining opaques in check_coroutine_obligations
This commit is contained in:
parent
ed10a53025
commit
4f958a4802
@ -1468,7 +1468,10 @@ fn opaque_type_cycle_error(
|
|||||||
err.emit()
|
err.emit()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn check_coroutine_obligations(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
pub(super) fn check_coroutine_obligations(
|
||||||
|
tcx: TyCtxt<'_>,
|
||||||
|
def_id: LocalDefId,
|
||||||
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
debug_assert!(matches!(tcx.def_kind(def_id), DefKind::Coroutine));
|
debug_assert!(matches!(tcx.def_kind(def_id), DefKind::Coroutine));
|
||||||
|
|
||||||
let typeck = tcx.typeck(def_id);
|
let typeck = tcx.typeck(def_id);
|
||||||
@ -1482,8 +1485,9 @@ pub(super) fn check_coroutine_obligations(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||||||
// typeck writeback gives us predicates with their regions erased.
|
// typeck writeback gives us predicates with their regions erased.
|
||||||
// As borrowck already has checked lifetimes, we do not need to do it again.
|
// As borrowck already has checked lifetimes, we do not need to do it again.
|
||||||
.ignoring_regions()
|
.ignoring_regions()
|
||||||
// Bind opaque types to `def_id` as they should have been checked by borrowck.
|
// Bind opaque types to type checking root, as they should have been checked by borrowck,
|
||||||
.with_opaque_type_inference(DefiningAnchor::Bind(def_id))
|
// but may show up in some cases, like when (root) obligations are stalled in the new solver.
|
||||||
|
.with_opaque_type_inference(DefiningAnchor::Bind(typeck.hir_owner.def_id))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let mut fulfillment_cx = <dyn TraitEngine<'_>>::new(&infcx);
|
let mut fulfillment_cx = <dyn TraitEngine<'_>>::new(&infcx);
|
||||||
@ -1513,6 +1517,16 @@ pub(super) fn check_coroutine_obligations(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||||||
let errors = fulfillment_cx.select_all_or_error(&infcx);
|
let errors = fulfillment_cx.select_all_or_error(&infcx);
|
||||||
debug!(?errors);
|
debug!(?errors);
|
||||||
if !errors.is_empty() {
|
if !errors.is_empty() {
|
||||||
infcx.err_ctxt().report_fulfillment_errors(errors);
|
return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check that any hidden types found when checking these stalled coroutine obligations
|
||||||
|
// are valid.
|
||||||
|
for (key, ty) in infcx.take_opaque_types() {
|
||||||
|
let hidden_type = infcx.resolve_vars_if_possible(ty.hidden_type);
|
||||||
|
let key = infcx.resolve_vars_if_possible(key);
|
||||||
|
sanity_check_found_hidden_type(tcx, key, hidden_type)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -567,7 +567,7 @@ rustc_queries! {
|
|||||||
separate_provide_extern
|
separate_provide_extern
|
||||||
}
|
}
|
||||||
|
|
||||||
query check_coroutine_obligations(key: LocalDefId) {
|
query check_coroutine_obligations(key: LocalDefId) -> Result<(), ErrorGuaranteed> {
|
||||||
desc { |tcx| "verify auto trait bounds for coroutine interior type `{}`", tcx.def_path_str(key) }
|
desc { |tcx| "verify auto trait bounds for coroutine interior type `{}`", tcx.def_path_str(key) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
17
tests/ui/coroutine/clone-rpit.rs
Normal file
17
tests/ui/coroutine/clone-rpit.rs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// revisions: current next
|
||||||
|
//[next] compile-flags: -Ztrait-solver=next
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(coroutines, coroutine_trait, coroutine_clone)]
|
||||||
|
|
||||||
|
// This stalls the goal `{coroutine} <: impl Clone`, since that has a nested goal
|
||||||
|
// of `{coroutine}: Clone`. That is only known if we can compute the generator
|
||||||
|
// witness types, which we don't know until after borrowck. When we later check
|
||||||
|
// the goal for correctness, we want to be able to bind the `impl Clone` opaque.
|
||||||
|
pub fn foo<'a, 'b>() -> impl Clone {
|
||||||
|
move |_: ()| {
|
||||||
|
let () = yield ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
Reference in New Issue
Block a user