forked from extern/nushell
fix(parser): mixed side effects of different choices in parse_oneof
(#14912)
# Description This PR fixes #14784. <img width="384" alt="image" src="https://github.com/user-attachments/assets/aac063a0-645d-4adb-a399-525bdb004999" /> Also fixes the related behavior of lsp: completion won't work in match/else blocks, because: 1. truncation in completion causes unmatched `{`, thus a parse error. 2. the parse error further leads to a state where the whole block expression marked as garbage <img width="453" alt="image" src="https://github.com/user-attachments/assets/aaf86ccc-646e-4b91-bb27-4b1737100ff2" /> Related PR: #14856, @tmillr I don't have any background knowledge of those `propagate_error`, @sgvictorino you may want to review this. # User-Facing Changes # Tests + Formatting # After Submitting
This commit is contained in:
@ -2426,7 +2426,7 @@ mod input_types {
|
||||
add_declarations(&mut engine_state);
|
||||
|
||||
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||
parse(
|
||||
let block = parse(
|
||||
&mut working_set,
|
||||
None,
|
||||
b"if false { 'a' } else { $foo }",
|
||||
@ -2437,6 +2437,30 @@ mod input_types {
|
||||
working_set.parse_errors.first(),
|
||||
Some(ParseError::VariableNotFound(_, _))
|
||||
));
|
||||
|
||||
let element = &block
|
||||
.pipelines
|
||||
.first()
|
||||
.unwrap()
|
||||
.elements
|
||||
.first()
|
||||
.unwrap()
|
||||
.expr;
|
||||
let Expr::Call(call) = &element.expr else {
|
||||
eprintln!("{:?}", element.expr);
|
||||
panic!("Expected Expr::Call");
|
||||
};
|
||||
let Expr::Keyword(else_kwd) = &call
|
||||
.arguments
|
||||
.get(2)
|
||||
.expect("This call of `if` should have 3 arguments")
|
||||
.expr()
|
||||
.unwrap()
|
||||
.expr
|
||||
else {
|
||||
panic!("Expected Expr::Keyword");
|
||||
};
|
||||
assert!(!matches!(else_kwd.expr.expr, Expr::Garbage))
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -2597,7 +2621,7 @@ mod record {
|
||||
let engine_state = EngineState::new();
|
||||
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||
let block = parse(&mut working_set, None, expr, false);
|
||||
assert!(working_set.parse_errors.first().is_none());
|
||||
assert!(working_set.parse_errors.is_empty());
|
||||
let pipeline_el_expr = &block
|
||||
.pipelines
|
||||
.first()
|
||||
|
Reference in New Issue
Block a user