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

Code before:
        let ParsedInternalCall { call, output } =
            parse_internal_call(working_set, spans[0], &spans[1..], decl_id);

        return Pipeline::from_vec(vec![Expression::new(
            working_set,
            Expr::Call(call),
            Span::concat(spans),
            output,
        )]);
    } else {
        working_set.error(ParseError::UnknownState(
            "internal error: let or const statements not found in core language".into(),
            Span::concat(spans),
        ))
    }

    working_set.error(ParseError::UnknownState(
        "internal error: let or const statement unparsable".into(),
        Span::concat(spans),
    ));

    garbage_pipeline(working_set, spans)
}

pub fn parse_const(working_set: &mut StateWorkingSet, spans: &[Span]) -> (Pipeline, Option<Span>) {
    trace!("parsing: const");

    // JT: Disabling check_name because it doesn't work with optional types in the declaration
    // if let Some(span) = check_name(working_set, spans) {
    //     return Pipeline::from_vec(vec![garbage(working_set, *span)]);
    // }

    if let Some(decl_id) = working_set.find_decl(b"const") {
        if spans.len() >= 4 {
            // This is a bit of by-hand parsing to get around the issue where we want to parse in the reverse order
            // so that the var-id created by the variable isn't visible in the expression that init it
            for span in spans.iter().enumerate() {
                let item = working_set.get_span_contents(*span.1);
                // const x = 'f', = at least start from index 2
                if item == b"=" && spans.len() > (span.0 + 1) && span.0 > 1 {
                    // Parse the rvalue as a subexpression
                    let rvalue_span = Span::concat(&spans[(span.0 + 1)..]);

                    let (rvalue_tokens, rvalue_error) = lex(
                        working_set.get_span_contents(rvalue_span),
                        rvalue_span.start,
                        &[],
                        &[],
                        false,
                    );
                    working_set.parse_errors.extend(rvalue_error);

Review comment (suggestion):
Maybe worth adding as part of the doccomment what the content of the `Option<Span>` is, otherwise those tuple return values are hard to deal with.

Code after:
        let ParsedInternalCall { call, output } =
            parse_internal_call(working_set, spans[0], &spans[1..], decl_id);

        return Pipeline::from_vec(vec![Expression::new(
            working_set,
            Expr::Call(call),
            Span::concat(spans),
            output,
        )]);
    } else {
        working_set.error(ParseError::UnknownState(
            "internal error: let or const statements not found in core language".into(),
            Span::concat(spans),
        ))
    }

    working_set.error(ParseError::UnknownState(
        "internal error: let or const statement unparsable".into(),
        Span::concat(spans),
    ));

    garbage_pipeline(working_set, spans)
}

/// Additionally returns a span encompassing the variable name, if successful.
pub fn parse_const(working_set: &mut StateWorkingSet, spans: &[Span]) -> (Pipeline, Option<Span>) {
    trace!("parsing: const");

    // JT: Disabling check_name because it doesn't work with optional types in the declaration
    // if let Some(span) = check_name(working_set, spans) {
    //     return Pipeline::from_vec(vec![garbage(working_set, *span)]);
    // }

    if let Some(decl_id) = working_set.find_decl(b"const") {
        if spans.len() >= 4 {
            // This is a bit of by-hand parsing to get around the issue where we want to parse in the reverse order
            // so that the var-id created by the variable isn't visible in the expression that init it
            for span in spans.iter().enumerate() {
                let item = working_set.get_span_contents(*span.1);
                // const x = 'f', = at least start from index 2
                if item == b"=" && spans.len() > (span.0 + 1) && span.0 > 1 {
                    // Parse the rvalue as a subexpression
                    let rvalue_span = Span::concat(&spans[(span.0 + 1)..]);

                    let (rvalue_tokens, rvalue_error) = lex(
                        working_set.get_span_contents(rvalue_span),
                        rvalue_span.start,
                        &[],
                        &[],
                        false,
                    );