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.rs | 42 |
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())?; |