Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Deduplicate needed parentheses suggestion code
  • Loading branch information
estebank committed May 2, 2019
commit f6a4b5270a0007e950546828a7f6fc7c54354b96
16 changes: 5 additions & 11 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4177,17 +4177,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
if let Some(sp) = tcx.sess.parse_sess.abiguous_block_expr_parse
.borrow().get(&sp)
{
if let Ok(snippet) = tcx.sess.source_map()
.span_to_snippet(*sp)
{
err.span_suggestion(
*sp,
"parentheses are required to parse this \
as an expression",
format!("({})", snippet),
Applicability::MachineApplicable,
);
}
tcx.sess.parse_sess.expr_parentheses_needed(
&mut err,
*sp,
None,
);
}
err.emit();
oprnd_t = tcx.types.err;
Expand Down
23 changes: 22 additions & 1 deletion src/libsyntax/parse/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::tokenstream::{TokenStream, TokenTree};
use crate::diagnostics::plugin::ErrorMap;
use crate::print::pprust::token_to_string;

use errors::{FatalError, Level, Handler, ColorConfig, Diagnostic, DiagnosticBuilder};
use errors::{Applicability, FatalError, Level, Handler, ColorConfig, Diagnostic, DiagnosticBuilder};
use rustc_data_structures::sync::{Lrc, Lock};
use syntax_pos::{Span, SourceFile, FileName, MultiSpan};
use log::debug;
Expand Down Expand Up @@ -47,6 +47,9 @@ pub struct ParseSess {
included_mod_stack: Lock<Vec<PathBuf>>,
source_map: Lrc<SourceMap>,
pub buffered_lints: Lock<Vec<BufferedEarlyLint>>,
/// 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>>,
}

Expand Down Expand Up @@ -95,6 +98,24 @@ impl ParseSess {
});
});
}

/// Extend an error with a suggestion to wrap an expression with parentheses to allow the
/// parser to continue parsing the following operation as part of the same expression.
pub fn expr_parentheses_needed(
&self,
err: &mut DiagnosticBuilder<'_>,
span: Span,
alt_snippet: Option<String>,
) {
if let Some(snippet) = self.source_map().span_to_snippet(span).ok().or(alt_snippet) {
err.span_suggestion(
span,
"parentheses are required to parse this as an expression",
format!("({})", snippet),
Applicability::MachineApplicable,
);
}
}
}

#[derive(Clone)]
Expand Down
29 changes: 6 additions & 23 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2931,14 +2931,7 @@ impl<'a> Parser<'a> {
if let Some(sp) = self.sess.abiguous_block_expr_parse.borrow()
.get(&sp)
{
if let Ok(snippet) = self.sess.source_map().span_to_snippet(*sp) {
err.span_suggestion(
*sp,
"parentheses are required to parse this as an expression",
format!("({})", snippet),
Applicability::MachineApplicable,
);
}
self.sess.expr_parentheses_needed(&mut err, *sp, None);
}
err.span_label(self.span, "expected expression");
return Err(err);
Expand Down Expand Up @@ -3657,14 +3650,11 @@ impl<'a> Parser<'a> {
pprust::token_to_string(&self.token),
));
err.span_label(self.span, "expected expression");
let snippet = self.sess.source_map().span_to_snippet(lhs.span)
.unwrap_or_else(|_| pprust::expr_to_string(&lhs));
err.span_suggestion(
self.sess.expr_parentheses_needed(
&mut err,
lhs.span,
"parentheses are required to parse this as an expression",
format!("({})", snippet),
Applicability::MachineApplicable,
);
Some(pprust::expr_to_string(&lhs),
));
err.emit();
}
}
Expand Down Expand Up @@ -4979,14 +4969,7 @@ impl<'a> Parser<'a> {
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 Ok(snippet) = self.sess.source_map().span_to_snippet(*sp) {
err.span_suggestion(
*sp,
"parentheses are required to parse this as an expression",
format!("({})", snippet),
Applicability::MachineApplicable,
);
}
self.sess.expr_parentheses_needed(&mut err, *sp, None);
}
return Err(err);
}
Expand Down