Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/mir/lower.rs')
-rw-r--r--crates/hir-ty/src/mir/lower.rs54
1 files changed, 34 insertions, 20 deletions
diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs
index 9905d52214..922aee011c 100644
--- a/crates/hir-ty/src/mir/lower.rs
+++ b/crates/hir-ty/src/mir/lower.rs
@@ -105,9 +105,14 @@ pub enum MirLowerError {
/// A token to ensuring that each drop scope is popped at most once, thanks to the compiler that checks moves.
struct DropScopeToken;
impl DropScopeToken {
- fn pop_and_drop(self, ctx: &mut MirLowerCtx<'_>, current: BasicBlockId) -> BasicBlockId {
+ fn pop_and_drop(
+ self,
+ ctx: &mut MirLowerCtx<'_>,
+ current: BasicBlockId,
+ span: MirSpan,
+ ) -> BasicBlockId {
std::mem::forget(self);
- ctx.pop_drop_scope_internal(current)
+ ctx.pop_drop_scope_internal(current, span)
}
/// It is useful when we want a drop scope is syntaxically closed, but we don't want to execute any drop
@@ -582,7 +587,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
self.lower_loop(current, place, *label, expr_id.into(), |this, begin| {
let scope = this.push_drop_scope();
if let Some((_, mut current)) = this.lower_expr_as_place(begin, *body, true)? {
- current = scope.pop_and_drop(this, current);
+ current = scope.pop_and_drop(this, current, body.into());
this.set_goto(current, begin, expr_id.into());
} else {
scope.pop_assume_dropped(this);
@@ -720,7 +725,8 @@ impl<'ctx> MirLowerCtx<'ctx> {
.ok_or(MirLowerError::ContinueWithoutLoop)?,
};
let begin = loop_data.begin;
- current = self.drop_until_scope(loop_data.drop_scope_index, current);
+ current =
+ self.drop_until_scope(loop_data.drop_scope_index, current, expr_id.into());
self.set_goto(current, begin, expr_id.into());
Ok(None)
}
@@ -759,7 +765,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
self.current_loop_blocks.as_ref().unwrap().drop_scope_index,
),
};
- current = self.drop_until_scope(drop_scope, current);
+ current = self.drop_until_scope(drop_scope, current, expr_id.into());
self.set_goto(current, end, expr_id.into());
Ok(None)
}
@@ -773,7 +779,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
return Ok(None);
}
}
- current = self.drop_until_scope(0, current);
+ current = self.drop_until_scope(0, current, expr_id.into());
self.set_terminator(current, TerminatorKind::Return, expr_id.into());
Ok(None)
}
@@ -1782,7 +1788,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
return Ok(None);
};
self.push_fake_read(c, p, expr.into());
- current = scope2.pop_and_drop(self, c);
+ current = scope2.pop_and_drop(self, c, expr.into());
}
}
}
@@ -1793,7 +1799,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
};
current = c;
}
- current = scope.pop_and_drop(self, current);
+ current = scope.pop_and_drop(self, current, span);
Ok(Some(current))
}
@@ -1873,9 +1879,14 @@ impl<'ctx> MirLowerCtx<'ctx> {
}
}
- fn drop_until_scope(&mut self, scope_index: usize, mut current: BasicBlockId) -> BasicBlockId {
+ fn drop_until_scope(
+ &mut self,
+ scope_index: usize,
+ mut current: BasicBlockId,
+ span: MirSpan,
+ ) -> BasicBlockId {
for scope in self.drop_scopes[scope_index..].to_vec().iter().rev() {
- self.emit_drop_and_storage_dead_for_scope(scope, &mut current);
+ self.emit_drop_and_storage_dead_for_scope(scope, &mut current, span);
}
current
}
@@ -1891,17 +1902,22 @@ impl<'ctx> MirLowerCtx<'ctx> {
}
/// Don't call directly
- fn pop_drop_scope_internal(&mut self, mut current: BasicBlockId) -> BasicBlockId {
+ fn pop_drop_scope_internal(
+ &mut self,
+ mut current: BasicBlockId,
+ span: MirSpan,
+ ) -> BasicBlockId {
let scope = self.drop_scopes.pop().unwrap();
- self.emit_drop_and_storage_dead_for_scope(&scope, &mut current);
+ self.emit_drop_and_storage_dead_for_scope(&scope, &mut current, span);
current
}
fn pop_drop_scope_assert_finished(
&mut self,
mut current: BasicBlockId,
+ span: MirSpan,
) -> Result<BasicBlockId> {
- current = self.pop_drop_scope_internal(current);
+ current = self.pop_drop_scope_internal(current, span);
if !self.drop_scopes.is_empty() {
implementation_error!("Mismatched count between drop scope push and pops");
}
@@ -1912,6 +1928,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
&mut self,
scope: &DropScope,
current: &mut Idx<BasicBlock>,
+ span: MirSpan,
) {
for &l in scope.locals.iter().rev() {
if !self.result.locals[l].ty.clone().is_copy(self.db, self.owner) {
@@ -1919,13 +1936,10 @@ impl<'ctx> MirLowerCtx<'ctx> {
self.set_terminator(
prev,
TerminatorKind::Drop { place: l.into(), target: *current, unwind: None },
- MirSpan::Unknown,
+ span,
);
}
- self.push_statement(
- *current,
- StatementKind::StorageDead(l).with_span(MirSpan::Unknown),
- );
+ self.push_statement(*current, StatementKind::StorageDead(l).with_span(span));
}
}
}
@@ -2002,7 +2016,7 @@ pub fn mir_body_for_closure_query(
|_| true,
)?;
if let Some(current) = ctx.lower_expr_to_place(*root, return_slot().into(), current)? {
- let current = ctx.pop_drop_scope_assert_finished(current)?;
+ let current = ctx.pop_drop_scope_assert_finished(current, root.into())?;
ctx.set_terminator(current, TerminatorKind::Return, (*root).into());
}
let mut upvar_map: FxHashMap<LocalId, Vec<(&CapturedItem, usize)>> = FxHashMap::default();
@@ -2146,7 +2160,7 @@ pub fn lower_to_mir(
ctx.lower_params_and_bindings([].into_iter(), binding_picker)?
};
if let Some(current) = ctx.lower_expr_to_place(root_expr, return_slot().into(), current)? {
- let current = ctx.pop_drop_scope_assert_finished(current)?;
+ let current = ctx.pop_drop_scope_assert_finished(current, root_expr.into())?;
ctx.set_terminator(current, TerminatorKind::Return, root_expr.into());
}
Ok(ctx.result)