Core implementation for lowering HIR constructs to MIR bodies. This method handles the common logic for converting thunks, closures, and type constructors into MIR function bodies. It manages parameter binding, capture handling, and basic block construction. # Parameters - `source`: The type of construct being lowered (thunk, closure, constructor) - `span`: Source location for error reporting -
(
mut self,
source: Source<'heap>,
span: SpanId,
params: impl IntoIterator<Item = Typed<Binder<'heap>>>,
returns: TypeId,
captures: Option<(&MixedBitSet
| 173 | /// |
| 174 | /// The definition ID of the newly created MIR body. |
| 175 | fn lower_impl( |
| 176 | mut self, |
| 177 | source: Source<'heap>, |
| 178 | span: SpanId, |
| 179 | params: impl IntoIterator<Item = Typed<Binder<'heap>>>, |
| 180 | returns: TypeId, |
| 181 | captures: Option<(&MixedBitSet<VarId>, TypeId)>, |
| 182 | on_block: impl FnOnce(&mut Self, &mut CurrentBlock<'mir, 'heap>) -> Spanned<Operand<'heap>>, |
| 183 | ) -> DefId { |
| 184 | let mut args = 0; |
| 185 | |
| 186 | // Closures and type constructors are fat pointers, the reason is that they are |
| 187 | // constructible by users and therefore always correspond to a fat call. |
| 188 | // In the future we might want to specialize `ctor` in a way that allows us to move them to |
| 189 | // be thin calls (although that would require that we move functions into a separate type |
| 190 | // from closures). |
| 191 | let env = if matches!( |
| 192 | source, |
| 193 | Source::Closure(_, _) | Source::Ctor(_) | Source::GraphReadFilter(_) |
| 194 | ) { |
| 195 | let r#type = if let Some((_, type_id)) = captures { |
| 196 | debug_assert_matches!(source, Source::Closure(..) | Source::GraphReadFilter(..)); |
| 197 | type_id |
| 198 | } else { |
| 199 | // In case there are no captures, the environment will always be a unit type (aka |
| 200 | // Tuple). |
| 201 | debug_assert_matches!(source, Source::Ctor(..)); |
| 202 | TypeBuilder::spanned(span, self.context.mir.env).tuple([] as [TypeId; 0]) |
| 203 | }; |
| 204 | |
| 205 | let local = self.local_decls.push(LocalDecl { |
| 206 | span, |
| 207 | r#type, |
| 208 | name: None, |
| 209 | }); |
| 210 | |
| 211 | args += 1; |
| 212 | |
| 213 | local |
| 214 | } else { |
| 215 | debug_assert!(captures.is_none()); |
| 216 | |
| 217 | // ends up never being used |
| 218 | Local::MAX |
| 219 | }; |
| 220 | |
| 221 | for Typed { |
| 222 | value: Binder { id, span, name }, |
| 223 | r#type, |
| 224 | } in params |
| 225 | { |
| 226 | let local = self.local_decls.push(LocalDecl { span, r#type, name }); |
| 227 | args += 1; |
| 228 | |
| 229 | self.locals.insert(id, local); |
| 230 | } |
| 231 | |
| 232 | let mut block = CurrentBlock::new(self.context.mir.heap, self.context.mir.interner); |