diff --git a/crates/nu-parser/src/parser.rs b/crates/nu-parser/src/parser.rs index 79ada981ab..9c203d37d0 100644 --- a/crates/nu-parser/src/parser.rs +++ b/crates/nu-parser/src/parser.rs @@ -5272,15 +5272,43 @@ pub fn parse_record(working_set: &mut StateWorkingSet, span: Span) -> Expression idx += 1; if idx == tokens.len() { - working_set.error(ParseError::Expected("record", span)); - return garbage(span); + working_set.error(ParseError::Expected( + "':'", + Span::new(curr_span.end, curr_span.end), + )); + output.push(RecordItem::Pair( + garbage(curr_span), + garbage(Span::new(curr_span.end, curr_span.end)), + )); + break; } - let colon = working_set.get_span_contents(tokens[idx].span); + let colon_span = tokens[idx].span; + let colon = working_set.get_span_contents(colon_span); idx += 1; - if idx == tokens.len() || colon != b":" { - //FIXME: need better error - working_set.error(ParseError::Expected("record", span)); - return garbage(span); + if colon != b":" { + working_set.error(ParseError::Expected( + "':'", + Span::new(colon_span.start, colon_span.start), + )); + output.push(RecordItem::Pair( + field, + garbage(Span::new( + colon_span.start, + tokens[tokens.len() - 1].span.end, + )), + )); + break; + } + if idx == tokens.len() { + working_set.error(ParseError::Expected( + "value for record field", + Span::new(colon_span.end, colon_span.end), + )); + output.push(RecordItem::Pair( + garbage(Span::new(curr_span.start, colon_span.end)), + garbage(Span::new(colon_span.end, tokens[tokens.len() - 1].span.end)), + )); + break; } let value = parse_value(working_set, tokens[idx].span, &SyntaxShape::Any); idx += 1; diff --git a/src/tests/test_parser.rs b/src/tests/test_parser.rs index d3911606dc..e8da07a70f 100644 --- a/src/tests/test_parser.rs +++ b/src/tests/test_parser.rs @@ -763,3 +763,14 @@ fn properly_typecheck_rest_param() -> TestResult { fn implied_collect_has_compatible_type() -> TestResult { run_test(r#"let idx = 3 | $in; $idx < 1"#, "false") } + +#[test] +fn record_expected_colon() -> TestResult { + fail_test(r#"{ a: 2 b }"#, "expected ':'")?; + fail_test(r#"{ a: 2 b 3 }"#, "expected ':'") +} + +#[test] +fn record_missing_value() -> TestResult { + fail_test(r#"{ a: 2 b: }"#, "expected value for record field") +}