raw_identifier_spans: Lock::new(Vec::new()),
registered_diagnostics: Lock::new(ErrorMap::new()),
buffered_lints: Lock::new(vec![]),
- abiguous_block_expr_parse: Lock::new(FxHashMap::default()),
+ ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
}
}
/// Contains the spans of block expressions that could have been incomplete based on the
/// operation token that followed it, but that the parser cannot identify without further
/// analysis.
- pub abiguous_block_expr_parse: Lock<FxHashMap<Span, Span>>,
+ pub ambiguous_block_expr_parse: Lock<FxHashMap<Span, Span>>,
}
impl ParseSess {
included_mod_stack: Lock::new(vec![]),
source_map,
buffered_lints: Lock::new(vec![]),
- abiguous_block_expr_parse: Lock::new(FxHashMap::default()),
+ ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
}
}
self.this_token_descr());
let mut err = self.fatal(&msg);
let sp = self.sess.source_map().start_point(self.span);
- if let Some(sp) = self.sess.abiguous_block_expr_parse.borrow()
+ if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow()
.get(&sp)
{
self.sess.expr_parentheses_needed(&mut err, *sp, None);
return Ok(lhs);
}
(false, _) => {} // continue parsing the expression
- (true, Some(AssocOp::Multiply)) | // `{ 42 } *foo = bar;`
+ // An exhaustive check is done in the following block, but these are checked first
+ // because they *are* ambiguous but also reasonable looking incorrect syntax, so we
+ // want to keep their span info to improve diagnostics in these cases in a later stage.
+ (true, Some(AssocOp::Multiply)) | // `{ 42 } *foo = bar;` or `{ 42 } * 3`
(true, Some(AssocOp::Subtract)) | // `{ 42 } -5`
(true, Some(AssocOp::Add)) => { // `{ 42 } + 42
// These cases are ambiguous and can't be identified in the parser alone
let sp = self.sess.source_map().start_point(self.span);
- self.sess.abiguous_block_expr_parse.borrow_mut().insert(sp, lhs.span);
+ self.sess.ambiguous_block_expr_parse.borrow_mut().insert(sp, lhs.span);
return Ok(lhs);
}
(true, Some(ref op)) if !op.can_continue_expr_unambiguously() => {
let mut err = self.fatal(&msg);
err.span_label(self.span, format!("expected {}", expected));
let sp = self.sess.source_map().start_point(self.span);
- if let Some(sp) = self.sess.abiguous_block_expr_parse.borrow().get(&sp) {
+ if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&sp) {
self.sess.expr_parentheses_needed(&mut err, *sp, None);
}
return Err(err);
}
}
+ /// This operator could be used to follow a block unambiguously.
+ ///
+ /// This is used for error recovery at the moment, providing a suggestion to wrap blocks with
+ /// parentheses while having a high degree of confidence on the correctness of the suggestion.
pub fn can_continue_expr_unambiguously(&self) -> bool {
use AssocOp::*;
match self {
Colon => true, // `{ 42 }: usize`
_ => false,
}
-
}
}