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

Method resolve_function_args

prqlc/prqlc/src/semantic/resolver/functions.rs:214–348  ·  view source on GitHub ↗

Resolves function arguments. Will return `Err(func)` is partial application is required.

(
        &mut self,
        #[allow(clippy::boxed_local)] to_resolve: Box<Func>,
    )

Source from the content-addressed store, hash-verified

212
213 /// Resolves function arguments. Will return `Err(func)` is partial application is required.
214 fn resolve_function_args(
215 &mut self,
216 #[allow(clippy::boxed_local)] to_resolve: Box<Func>,
217 ) -> Result<Result<Box<Func>, Box<Func>>> {
218 let mut closure = Box::new(Func {
219 args: vec![Expr::new(Literal::Null); to_resolve.args.len()],
220 ..*to_resolve
221 });
222 let mut partial_application_position = None;
223
224 let func_name = &closure.name_hint;
225
226 let (relations, other): (Vec<_>, Vec<_>) = zip(&closure.params, to_resolve.args)
227 .enumerate()
228 .partition(|(_, (param, _))| {
229 let is_relation = param
230 .ty
231 .as_ref()
232 .map(|t| t.is_relation())
233 .unwrap_or_default();
234
235 is_relation
236 });
237
238 let has_relations = !relations.is_empty();
239
240 // resolve relational args
241 if has_relations {
242 self.root_mod.module.shadow(NS_THIS);
243 self.root_mod.module.shadow(NS_THAT);
244
245 // First, resolve all relational arguments
246 let mut resolved_relations = Vec::new();
247 for (pos, (index, (param, mut arg))) in relations.into_iter().with_position() {
248 let is_last = matches!(pos, Position::Last | Position::Only);
249
250 // just fold the argument alone
251 if partial_application_position.is_none() {
252 arg = self
253 .fold_and_type_check(arg, param, func_name)?
254 .unwrap_or_else(|a| {
255 partial_application_position = Some(index);
256 a
257 });
258 }
259 log::debug!("resolved arg to {}", arg.kind.as_ref());
260
261 resolved_relations.push((index, arg, is_last));
262 }
263
264 // Then, add relation frames into scope
265 for (index, arg, is_last) in resolved_relations {
266 if partial_application_position.is_none() {
267 let frame = arg.lineage.as_ref().ok_or_else(|| {
268 // Provide helpful error for empty arrays/tuples used directly
269 // (not from functions like std.from_text which set lineage properly)
270 match &arg.kind {
271 ExprKind::Array(v) if v.is_empty() => Error::new(Reason::Expected {

Callers 1

fold_functionMethod · 0.80

Calls 14

mapMethod · 0.80
is_relationMethod · 0.80
is_emptyMethod · 0.80
shadowMethod · 0.80
into_iterMethod · 0.80
fold_and_type_checkMethod · 0.80
pushMethod · 0.80
with_spanMethod · 0.80
insert_frameMethod · 0.80
lenMethod · 0.80
fold_within_namespaceMethod · 0.80

Tested by

no test coverage detected