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.rs42
1 files changed, 34 insertions, 8 deletions
diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs
index d0f739e6ac..7e582c03ef 100644
--- a/crates/hir-ty/src/mir/lower.rs
+++ b/crates/hir-ty/src/mir/lower.rs
@@ -1810,9 +1810,20 @@ impl<'ctx> MirLowerCtx<'ctx> {
fn lower_params_and_bindings(
&mut self,
params: impl Iterator<Item = (PatId, Ty)> + Clone,
+ self_binding: Option<(BindingId, Ty)>,
pick_binding: impl Fn(BindingId) -> bool,
) -> Result<BasicBlockId> {
let base_param_count = self.result.param_locals.len();
+ let self_binding = match self_binding {
+ Some((self_binding, ty)) => {
+ let local_id = self.result.locals.alloc(Local { ty });
+ self.drop_scopes.last_mut().unwrap().locals.push(local_id);
+ self.result.binding_locals.insert(self_binding, local_id);
+ self.result.param_locals.push(local_id);
+ Some(self_binding)
+ }
+ None => None,
+ };
self.result.param_locals.extend(params.clone().map(|(it, ty)| {
let local_id = self.result.locals.alloc(Local { ty });
self.drop_scopes.last_mut().unwrap().locals.push(local_id);
@@ -1838,9 +1849,23 @@ impl<'ctx> MirLowerCtx<'ctx> {
}
}
let mut current = self.result.start_block;
- for ((param, _), local) in
- params.zip(self.result.param_locals.clone().into_iter().skip(base_param_count))
- {
+ if let Some(self_binding) = self_binding {
+ let local = self.result.param_locals.clone()[base_param_count];
+ if local != self.binding_local(self_binding)? {
+ let r = self.match_self_param(self_binding, current, local)?;
+ if let Some(b) = r.1 {
+ self.set_terminator(b, TerminatorKind::Unreachable, MirSpan::SelfParam);
+ }
+ current = r.0;
+ }
+ }
+ let local_params = self
+ .result
+ .param_locals
+ .clone()
+ .into_iter()
+ .skip(base_param_count + self_binding.is_some() as usize);
+ for ((param, _), local) in params.zip(local_params) {
if let Pat::Bind { id, .. } = self.body[param] {
if local == self.binding_local(id)? {
continue;
@@ -2019,6 +2044,7 @@ pub fn mir_body_for_closure_query(
};
let current = ctx.lower_params_and_bindings(
args.iter().zip(sig.params().iter()).map(|(it, y)| (*it, y.clone())),
+ None,
|_| true,
)?;
if let Some(current) = ctx.lower_expr_to_place(*root, return_slot().into(), current)? {
@@ -2149,16 +2175,16 @@ pub fn lower_to_mir(
let substs = TyBuilder::placeholder_subst(db, fid);
let callable_sig =
db.callable_item_signature(fid.into()).substitute(Interner, &substs);
+ let mut params = callable_sig.params().iter();
+ let self_param = body.self_param.and_then(|id| Some((id, params.next()?.clone())));
break 'b ctx.lower_params_and_bindings(
- body.params
- .iter()
- .zip(callable_sig.params().iter())
- .map(|(it, y)| (*it, y.clone())),
+ body.params.iter().zip(params).map(|(it, y)| (*it, y.clone())),
+ self_param,
binding_picker,
)?;
}
}
- ctx.lower_params_and_bindings([].into_iter(), binding_picker)?
+ ctx.lower_params_and_bindings([].into_iter(), None, 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, root_expr.into())?;