Repository: nushell/nushell
File: crates/nu-parser/src/parser.rs (Rust)

Code before:
                working_set,
                Expr::Keyword(Box::new(keyword.clone())),
                keyword.span.merge(keyword.expr.span),
                keyword.expr.ty,
            )
        }
        _ => {
            // All other cases are single-span values
            let arg_span = spans[*spans_idx];

            parse_value(working_set, arg_span, shape)
        }
    }
}

pub struct ParsedInternalCall {
    pub call: Box<Call>,
    pub output: Type,
}

pub fn parse_internal_call(
    working_set: &mut StateWorkingSet,
    command_span: Span,
    spans: &[Span],
    decl_id: DeclId,
    lite: bool,
) -> ParsedInternalCall {
    trace!("parsing: internal call (decl id: {})", decl_id.get());

    let mut call = Call::new(command_span);
    call.decl_id = decl_id;
    call.head = command_span;
    let _ = working_set.add_span(call.head);

    let decl = working_set.get_decl(decl_id);
    let signature = working_set.get_signature(decl);
    let output = signature.get_output_type();

    let deprecation = decl.deprecation_info();

    // storing the var ID for later due to borrowing issues
    let lib_dirs_var_id = match decl.name() {
        "use" | "overlay use" | "source-env" if decl.is_keyword() => {
            find_dirs_var(working_set, LIB_DIRS_VAR)
        }
        "nu-check" if decl.is_builtin() => find_dirs_var(working_set, LIB_DIRS_VAR),
        _ => None,
    };

    // The index into the positional parameter in the definition
    let mut positional_idx = 0;

Review comment (suggestion):
With it being broadly used, that should have an externally visible doccomment explaining when to use it. The stretch solution would be a binary enum which makes the meaning obvious even when reading the call sites before hovering.

Code after:
            if *spans_idx >= spans.len() {
                working_set.error(ParseError::KeywordMissingArgument(
                    arg.to_string(),
                    String::from_utf8_lossy(keyword).into(),
                    Span::new(spans[*spans_idx - 1].end, spans[*spans_idx - 1].end),
                ));
                let keyword = Keyword {
                    keyword: keyword.as_slice().into(),
                    span: spans[*spans_idx - 1],
                    expr: Expression::garbage(working_set, arg_span),
                };
                return Expression::new(
                    working_set,
                    Expr::Keyword(Box::new(keyword)),
                    arg_span,
                    Type::Any,
                );
            }

            let keyword = Keyword {
                keyword: keyword.as_slice().into(),
                span: spans[*spans_idx - 1],
                expr: parse_multispan_value(working_set, spans, spans_idx, arg),
            };

            Expression::new(
                working_set,
                Expr::Keyword(Box::new(keyword.clone())),
                keyword.span.merge(keyword.expr.span),
                keyword.expr.ty,
            )
        }
        _ => {
            // All other cases are single-span values
            let arg_span = spans[*spans_idx];

            parse_value(working_set, arg_span, shape)
        }
    }
}

pub struct ParsedInternalCall {
    pub call: Box<Call>,
    pub output: Type,
    pub call_kind: CallKind,
}

/// Sometimes the arguments of an internal command need to be parsed in dedicated functions, e.g. `parse_module`.
/// If so, `parse_internal_call` should be called with the appropriate parsing level to avoid repetition.
///
/// Defaults to `ArgumentParsingLevel::Full`