MCPcopy Index your code
hub / github.com/RustPython/RustPython / make_closure

Method make_closure

crates/codegen/src/compile.rs:4651–4795  ·  view source on GitHub ↗

Loads closure variables if needed and creates a function object = compiler_make_closure

(
        &mut self,
        code: CodeObject,
        flags: bytecode::MakeFunctionFlags,
    )

Source from the content-addressed store, hash-verified

4649 /// Loads closure variables if needed and creates a function object
4650 // = compiler_make_closure
4651 fn make_closure(
4652 &mut self,
4653 code: CodeObject,
4654 flags: bytecode::MakeFunctionFlags,
4655 ) -> CompileResult<()> {
4656 // Handle free variables (closure)
4657 let has_freevars = !code.freevars.is_empty();
4658 if has_freevars {
4659 // Build closure tuple by loading free variables
4660
4661 for var in &code.freevars {
4662 // Special case: If a class contains a method with a
4663 // free variable that has the same name as a method,
4664 // the name will be considered free *and* local in the
4665 // class. It should be handled by the closure, as
4666 // well as by the normal name lookup logic.
4667
4668 // Get reference type using our get_ref_type function
4669 let ref_type = self.get_ref_type(var).map_err(|e| self.error(e))?;
4670
4671 // Get parent code info
4672 let parent_code = self.code_stack.last().unwrap();
4673 let cellvars_len = parent_code.metadata.cellvars.len();
4674
4675 // Look up the variable index based on reference type
4676 let idx = match ref_type {
4677 SymbolScope::Cell => parent_code
4678 .metadata
4679 .cellvars
4680 .get_index_of(var)
4681 .or_else(|| {
4682 parent_code
4683 .metadata
4684 .freevars
4685 .get_index_of(var)
4686 .map(|i| i + cellvars_len)
4687 })
4688 .ok_or_else(|| {
4689 self.error(CodegenErrorType::SyntaxError(format!(
4690 "compiler_make_closure: cannot find '{var}' in parent vars",
4691 )))
4692 })?,
4693 SymbolScope::Free => parent_code
4694 .metadata
4695 .freevars
4696 .get_index_of(var)
4697 .map(|i| i + cellvars_len)
4698 .or_else(|| parent_code.metadata.cellvars.get_index_of(var))
4699 .ok_or_else(|| {
4700 self.error(CodegenErrorType::SyntaxError(format!(
4701 "compiler_make_closure: cannot find '{var}' in parent vars",
4702 )))
4703 })?,
4704 _ => {
4705 return Err(self.error(CodegenErrorType::SyntaxError(format!(
4706 "compiler_make_closure: unexpected ref_type {ref_type:?} for '{var}'",
4707 ))));
4708 }

Callers 9

compile_statementMethod · 0.80
compile_function_bodyMethod · 0.80
compile_function_defMethod · 0.80
compile_class_defMethod · 0.80
compile_expressionMethod · 0.80
compile_comprehensionMethod · 0.80

Calls 12

newFunction · 0.85
get_ref_typeMethod · 0.80
ok_or_elseMethod · 0.80
emit_load_constMethod · 0.80
ErrClass · 0.50
is_emptyMethod · 0.45
errorMethod · 0.45
unwrapMethod · 0.45
lastMethod · 0.45
lenMethod · 0.45
mapMethod · 0.45
containsMethod · 0.45

Tested by

no test coverage detected