Error on using yield
without also using #[coroutine]
on the closure
And suggest adding the `#[coroutine]` to the closure
This commit is contained in:
parent
a589632dad
commit
aef0f4024a
279 changed files with 1290 additions and 886 deletions
|
@ -422,49 +422,53 @@ pub fn analyze_coroutine_closure_captures<'a, 'tcx: 'a, T>(
|
|||
child_captures: impl IntoIterator<Item = &'a CapturedPlace<'tcx>>,
|
||||
mut for_each: impl FnMut((usize, &'a CapturedPlace<'tcx>), (usize, &'a CapturedPlace<'tcx>)) -> T,
|
||||
) -> impl Iterator<Item = T> + Captures<'a> + Captures<'tcx> {
|
||||
std::iter::from_coroutine(move || {
|
||||
let mut child_captures = child_captures.into_iter().enumerate().peekable();
|
||||
std::iter::from_coroutine(
|
||||
#[cfg_attr(not(bootstrap), coroutine)]
|
||||
move || {
|
||||
let mut child_captures = child_captures.into_iter().enumerate().peekable();
|
||||
|
||||
// One parent capture may correspond to several child captures if we end up
|
||||
// refining the set of captures via edition-2021 precise captures. We want to
|
||||
// match up any number of child captures with one parent capture, so we keep
|
||||
// peeking off this `Peekable` until the child doesn't match anymore.
|
||||
for (parent_field_idx, parent_capture) in parent_captures.into_iter().enumerate() {
|
||||
// Make sure we use every field at least once, b/c why are we capturing something
|
||||
// if it's not used in the inner coroutine.
|
||||
let mut field_used_at_least_once = false;
|
||||
// One parent capture may correspond to several child captures if we end up
|
||||
// refining the set of captures via edition-2021 precise captures. We want to
|
||||
// match up any number of child captures with one parent capture, so we keep
|
||||
// peeking off this `Peekable` until the child doesn't match anymore.
|
||||
for (parent_field_idx, parent_capture) in parent_captures.into_iter().enumerate() {
|
||||
// Make sure we use every field at least once, b/c why are we capturing something
|
||||
// if it's not used in the inner coroutine.
|
||||
let mut field_used_at_least_once = false;
|
||||
|
||||
// A parent matches a child if they share the same prefix of projections.
|
||||
// The child may have more, if it is capturing sub-fields out of
|
||||
// something that is captured by-move in the parent closure.
|
||||
while child_captures.peek().map_or(false, |(_, child_capture)| {
|
||||
child_prefix_matches_parent_projections(parent_capture, child_capture)
|
||||
}) {
|
||||
let (child_field_idx, child_capture) = child_captures.next().unwrap();
|
||||
// This analysis only makes sense if the parent capture is a
|
||||
// prefix of the child capture.
|
||||
assert!(
|
||||
child_capture.place.projections.len() >= parent_capture.place.projections.len(),
|
||||
"parent capture ({parent_capture:#?}) expected to be prefix of \
|
||||
// A parent matches a child if they share the same prefix of projections.
|
||||
// The child may have more, if it is capturing sub-fields out of
|
||||
// something that is captured by-move in the parent closure.
|
||||
while child_captures.peek().map_or(false, |(_, child_capture)| {
|
||||
child_prefix_matches_parent_projections(parent_capture, child_capture)
|
||||
}) {
|
||||
let (child_field_idx, child_capture) = child_captures.next().unwrap();
|
||||
// This analysis only makes sense if the parent capture is a
|
||||
// prefix of the child capture.
|
||||
assert!(
|
||||
child_capture.place.projections.len()
|
||||
>= parent_capture.place.projections.len(),
|
||||
"parent capture ({parent_capture:#?}) expected to be prefix of \
|
||||
child capture ({child_capture:#?})"
|
||||
);
|
||||
);
|
||||
|
||||
yield for_each(
|
||||
(parent_field_idx, parent_capture),
|
||||
(child_field_idx, child_capture),
|
||||
);
|
||||
yield for_each(
|
||||
(parent_field_idx, parent_capture),
|
||||
(child_field_idx, child_capture),
|
||||
);
|
||||
|
||||
field_used_at_least_once = true;
|
||||
field_used_at_least_once = true;
|
||||
}
|
||||
|
||||
// Make sure the field was used at least once.
|
||||
assert!(
|
||||
field_used_at_least_once,
|
||||
"we captured {parent_capture:#?} but it was not used in the child coroutine?"
|
||||
);
|
||||
}
|
||||
|
||||
// Make sure the field was used at least once.
|
||||
assert!(
|
||||
field_used_at_least_once,
|
||||
"we captured {parent_capture:#?} but it was not used in the child coroutine?"
|
||||
);
|
||||
}
|
||||
assert_eq!(child_captures.next(), None, "leftover child captures?");
|
||||
})
|
||||
assert_eq!(child_captures.next(), None, "leftover child captures?");
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn child_prefix_matches_parent_projections(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue