MCPcopy Create free account
hub / github.com/PRQL/prql / materialize_function

Method materialize_function

prqlc/prqlc/src/semantic/resolver/functions.rs:104–164  ·  view source on GitHub ↗
(&mut self, closure: Box<Func>)

Source from the content-addressed store, hash-verified

102
103 #[allow(clippy::boxed_local)]
104 fn materialize_function(&mut self, closure: Box<Func>) -> Result<Expr> {
105 log::debug!("stack_push for {}", closure.as_debug_name());
106
107 let (func_env, body, return_ty) = env_of_closure(*closure);
108
109 self.root_mod.module.stack_push(NS_PARAM, func_env);
110
111 // fold again, to resolve inner variables & functions
112 let body = self.fold_expr(body)?;
113
114 // remove param decls
115 log::debug!("stack_pop: {:?}", body.id);
116 let func_env = self.root_mod.module.stack_pop(NS_PARAM).unwrap();
117
118 Ok(if let ExprKind::Func(mut inner_closure) = body.kind {
119 // body couldn't been resolved - construct a closure to be evaluated later
120
121 inner_closure.env = func_env.into_exprs();
122
123 // Get the missing params (params that don't have args yet)
124 let missing = inner_closure.params[inner_closure.args.len()..].to_vec();
125
126 // Create wrapper params and add references to them as args to the inner closure
127 let mut wrapper_params = Vec::with_capacity(missing.len());
128 for (i, param) in missing.iter().enumerate() {
129 let param_name = format!("_partial_{i}");
130 let substitute_arg = Expr::new(Ident::from_path(vec![
131 NS_PARAM.to_string(),
132 param_name.clone(),
133 ]));
134 inner_closure.args.push(substitute_arg);
135 wrapper_params.push(FuncParam {
136 name: param_name,
137 ty: param.ty.clone(),
138 default_value: None,
139 });
140 }
141
142 Expr::new(ExprKind::Func(Box::new(Func {
143 name_hint: None,
144 args: vec![],
145 params: wrapper_params,
146 body: Box::new(Expr::new(ExprKind::Func(inner_closure))),
147
148 // these don't matter
149 named_params: Default::default(),
150 return_ty: Default::default(),
151 env: Default::default(),
152 })))
153 } else {
154 // resolved, return result
155
156 // make sure to use the resolved type
157 let mut body = body;
158 if let Some(ret_ty) = return_ty.map(|x| *x) {
159 body.ty = Some(ret_ty.clone());
160 }
161

Callers 1

fold_functionMethod · 0.80

Calls 10

env_of_closureFunction · 0.85
stack_pushMethod · 0.80
stack_popMethod · 0.80
into_exprsMethod · 0.80
lenMethod · 0.80
iterMethod · 0.80
pushMethod · 0.80
mapMethod · 0.80
FuncClass · 0.50
fold_exprMethod · 0.45

Tested by

no test coverage detected