Skip to content

Commit

Permalink
Do not insert unit expr into sequence in case of error
Browse files Browse the repository at this point in the history
  • Loading branch information
awelc committed Apr 7, 2024
1 parent 13cae0d commit c8dacc3
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2207,6 +2207,20 @@ fn optional_types(context: &mut Context, pts_opt: Option<Vec<P::Type>>) -> Optio

#[growing_stack]
fn sequence(context: &mut Context, loc: Loc, seq: P::Sequence) -> E::Sequence {
// removes an unresolved sequence item if it is the only item in the sequence
fn remove_single_unresolved(items: &mut VecDeque<E::SequenceItem>) -> Option<Box<E::Exp>> {
if items.len() != 1 {
return None;
}
let seq_item = items.pop_front().unwrap();
if let E::SequenceItem_::Seq(exp) = &seq_item.value {
if exp.value == E::Exp_::UnresolvedError {
return Some(exp.clone());
}
}
items.push_front(seq_item);
None
}
let (puses, pitems, maybe_last_semicolon_loc, pfinal_item) = seq;

let (new_scope, use_funs_builder) = uses(context, puses);
Expand All @@ -2219,11 +2233,17 @@ fn sequence(context: &mut Context, loc: Loc, seq: P::Sequence) -> E::Sequence {
let final_e_opt = pfinal_item.map(|item| exp(context, Box::new(item)));
let final_e = match final_e_opt {
None => {
let last_semicolon_loc = match maybe_last_semicolon_loc {
Some(l) => l,
None => loc,
};
Box::new(sp(last_semicolon_loc, E::Exp_::Unit { trailing: true }))
// if there is only one item in the sequence and it is unresolved, do not generated the
// final sequence unit-typed expression
if let Some(unresolved) = remove_single_unresolved(&mut items) {
unresolved
} else {
let last_semicolon_loc = match maybe_last_semicolon_loc {
Some(l) => l,
None => loc,
};
Box::new(sp(last_semicolon_loc, E::Exp_::Unit { trailing: true }))
}
}
Some(e) => e,
};
Expand Down
15 changes: 3 additions & 12 deletions external-crates/move/crates/move-compiler/src/parser/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1425,7 +1425,6 @@ fn parse_sequence(context: &mut Context) -> Result<Sequence, Box<Diagnostic>> {
let mut seq: Vec<SequenceItem> = vec![];
let mut last_semicolon_loc = None;
let mut eopt = None;
let mut parsing_error = false;
while context.tokens.peek() != Tok::RBrace {
// this helps when a sequence contains a comma-separated list without the ending token (in
// which case the parser would be likely fast-forwarded to EOF)
Expand Down Expand Up @@ -1464,7 +1463,9 @@ fn parse_sequence(context: &mut Context) -> Result<Sequence, Box<Diagnostic>> {
}
}
Err(diag) => {
parsing_error = true;
let err_exp = sp(context.tokens.current_token_loc(), Exp_::UnresolvedError);
let err_seq_item = SequenceItem_::Seq(Box::new(err_exp));
seq.push(sp(context.tokens.current_token_loc(), err_seq_item));
context.stop_set.remove(Tok::Semicolon);
advance_separated_items_error(
context,
Expand Down Expand Up @@ -1506,16 +1507,6 @@ fn parse_sequence(context: &mut Context) -> Result<Sequence, Box<Diagnostic>> {
if !context.at_stop_set() || context.tokens.at(Tok::RBrace) {
context.advance(); // consume (the RBrace)
}
if parsing_error && seq.is_empty() && eopt.is_none() {
// If there was a sequence item to parse and its parsing failed, return an error in the
// sequence rather than an empty sequence. We have to put error into `eopt`, otherwise later
// translation passes will make this into a sequence with only one sequence item having an
// error rather which can still trigger typing errors on incorrect returned values.
eopt = Some(sp(
context.tokens.current_token_loc(),
Exp_::UnresolvedError,
));
}
Ok((uses, seq, last_semicolon_loc, Box::new(eopt)))
}

Expand Down

0 comments on commit c8dacc3

Please sign in to comment.