Skip to content

Commit

Permalink
Emit missing unclosed delimiter errors
Browse files Browse the repository at this point in the history
  • Loading branch information
estebank committed Mar 7, 2019
1 parent c70a516 commit 51d0e86
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 55 deletions.
4 changes: 2 additions & 2 deletions src/librustc_metadata/cstore_impl.rs
Expand Up @@ -439,8 +439,8 @@ impl cstore::CStore {

let source_file = sess.parse_sess.source_map().new_source_file(source_name, def.body);
let local_span = Span::new(source_file.start_pos, source_file.end_pos, NO_EXPANSION);
let (body, errors) = source_file_to_stream(&sess.parse_sess, source_file, None);
emit_unclosed_delims(&errors, &sess.diagnostic());
let (body, mut errors) = source_file_to_stream(&sess.parse_sess, source_file, None);
emit_unclosed_delims(&mut errors, &sess.diagnostic());

// Mark the attrs as used
let attrs = data.get_item_attrs(id.index, sess);
Expand Down
14 changes: 9 additions & 5 deletions src/libsyntax/parse/parser.rs
Expand Up @@ -7798,7 +7798,10 @@ impl<'a> Parser<'a> {
attributes_allowed: bool,
) -> PResult<'a, Option<P<Item>>> {
let (ret, tokens) = self.collect_tokens(|this| {
this.parse_item_implementation(attrs, macros_allowed, attributes_allowed)
let item = this.parse_item_implementation(attrs, macros_allowed, attributes_allowed);
let diag = this.diagnostic();
emit_unclosed_delims(&mut this.unclosed_delims, diag);
item
})?;

// Once we've parsed an item and recorded the tokens we got while
Expand Down Expand Up @@ -8555,8 +8558,8 @@ impl<'a> Parser<'a> {
module: self.parse_mod_items(&token::Eof, lo)?,
span: lo.to(self.span),
});
emit_unclosed_delims(&self.unclosed_delims, self.diagnostic());
self.unclosed_delims.clear();
let diag = self.diagnostic();
emit_unclosed_delims(&mut self.unclosed_delims, diag);
krate
}

Expand Down Expand Up @@ -8587,8 +8590,8 @@ impl<'a> Parser<'a> {
}
}

pub fn emit_unclosed_delims(unclosed_delims: &[UnmatchedBrace], handler: &errors::Handler) {
for unmatched in unclosed_delims {
pub fn emit_unclosed_delims(unclosed_delims: &mut Vec<UnmatchedBrace>, handler: &errors::Handler) {
for unmatched in unclosed_delims.iter() {
let mut err = handler.struct_span_err(unmatched.found_span, &format!(
"incorrect close delimiter: `{}`",
pprust::token_to_string(&token::Token::CloseDelim(unmatched.found_delim)),
Expand All @@ -8602,4 +8605,5 @@ pub fn emit_unclosed_delims(unclosed_delims: &[UnmatchedBrace], handler: &errors
}
err.emit();
}
unclosed_delims.clear();
}
12 changes: 6 additions & 6 deletions src/libsyntax/parse/token.rs
Expand Up @@ -675,9 +675,9 @@ impl Nonterminal {
// FIXME(#43081): Avoid this pretty-print + reparse hack
let source = pprust::nonterminal_to_string(self);
let filename = FileName::macro_expansion_source_code(&source);
let (tokens_for_real, errors) =
let (tokens_for_real, mut errors) =
parse_stream_from_source_str(filename, source, sess, Some(span));
emit_unclosed_delims(&errors, &sess.span_diagnostic);
emit_unclosed_delims(&mut errors, &sess.span_diagnostic);

// During early phases of the compiler the AST could get modified
// directly (e.g., attributes added or removed) and the internal cache
Expand Down Expand Up @@ -740,13 +740,13 @@ fn prepend_attrs(sess: &ParseSess,
let source = pprust::attr_to_string(attr);
let macro_filename = FileName::macro_expansion_source_code(&source);
if attr.is_sugared_doc {
let (stream, errors) = parse_stream_from_source_str(
let (stream, mut errors) = parse_stream_from_source_str(
macro_filename,
source,
sess,
Some(span),
);
emit_unclosed_delims(&errors, &sess.span_diagnostic);
emit_unclosed_delims(&mut errors, &sess.span_diagnostic);
builder.push(stream);
continue
}
Expand All @@ -763,13 +763,13 @@ fn prepend_attrs(sess: &ParseSess,
// ... and for more complicated paths, fall back to a reparse hack that
// should eventually be removed.
} else {
let (stream, errors) = parse_stream_from_source_str(
let (stream, mut errors) = parse_stream_from_source_str(
macro_filename,
source,
sess,
Some(span),
);
emit_unclosed_delims(&errors, &sess.span_diagnostic);
emit_unclosed_delims(&mut errors, &sess.span_diagnostic);
brackets.push(stream);
}

Expand Down
4 changes: 2 additions & 2 deletions src/libsyntax_ext/proc_macro_server.rs
Expand Up @@ -410,13 +410,13 @@ impl server::TokenStream for Rustc<'_> {
stream.is_empty()
}
fn from_str(&mut self, src: &str) -> Self::TokenStream {
let (tokens, errors) = parse::parse_stream_from_source_str(
let (tokens, mut errors) = parse::parse_stream_from_source_str(
FileName::proc_macro_source_code(src.clone()),
src.to_string(),
self.sess,
Some(self.call_site),
);
emit_unclosed_delims(&errors, &self.sess.span_diagnostic);
emit_unclosed_delims(&mut errors, &self.sess.span_diagnostic);
tokens
}
fn to_string(&mut self, stream: &Self::TokenStream) -> String {
Expand Down
12 changes: 6 additions & 6 deletions src/test/ui/parser-recovery-2.stderr
@@ -1,9 +1,3 @@
error: unexpected token: `;`
--> $DIR/parser-recovery-2.rs:12:15
|
LL | let x = y.; //~ ERROR unexpected token
| ^

error: incorrect close delimiter: `)`
--> $DIR/parser-recovery-2.rs:8:5
|
Expand All @@ -13,6 +7,12 @@ LL | let x = foo(); //~ ERROR cannot find function `foo` in this scope
LL | ) //~ ERROR incorrect close delimiter: `)`
| ^ incorrect close delimiter

error: unexpected token: `;`
--> $DIR/parser-recovery-2.rs:12:15
|
LL | let x = y.; //~ ERROR unexpected token
| ^

error[E0425]: cannot find function `foo` in this scope
--> $DIR/parser-recovery-2.rs:7:17
|
Expand Down
16 changes: 7 additions & 9 deletions src/test/ui/resolve/token-error-correct-3.rs
Expand Up @@ -10,16 +10,14 @@ pub mod raw {
pub fn ensure_dir_exists<P: AsRef<Path>, F: FnOnce(&Path)>(path: P,
callback: F)
-> io::Result<bool> {
if !is_directory(path.as_ref()) { //~ ERROR: cannot find function `is_directory`
callback(path.as_ref(); //~ ERROR expected one of
fs::create_dir_all(path.as_ref()).map(|()| true) //~ ERROR: mismatched types
//~^ expected (), found enum `std::result::Result`
//~| expected type `()`
//~| found type `std::result::Result<bool, std::io::Error>`
//~| expected one of
if !is_directory(path.as_ref()) {
//~^ ERROR cannot find function `is_directory`
callback(path.as_ref();
//~^ ERROR expected one of
//~| ERROR this function takes 1 parameter but 2 parameters were supplied
fs::create_dir_all(path.as_ref()).map(|()| true)
} else {
//~^ ERROR: expected one of
//~| unexpected token
//~^ ERROR incorrect close delimiter: `}`
Ok(false);
}

Expand Down
49 changes: 24 additions & 25 deletions src/test/ui/resolve/token-error-correct-3.stderr
@@ -1,39 +1,38 @@
error: expected one of `)`, `,`, `.`, `?`, or an operator, found `;`
--> $DIR/token-error-correct-3.rs:14:35
|
LL | callback(path.as_ref(); //~ ERROR expected one of
| - ^
| | |
| | help: `)` may belong here
| unclosed delimiter

error: expected one of `.`, `;`, `?`, `}`, or an operator, found `)`
--> $DIR/token-error-correct-3.rs:20:9
error: incorrect close delimiter: `}`
--> $DIR/token-error-correct-3.rs:19:9
|
LL | fs::create_dir_all(path.as_ref()).map(|()| true) //~ ERROR: mismatched types
| - expected one of `.`, `;`, `?`, `}`, or an operator here
LL | if !is_directory(path.as_ref()) {
| - close delimiter possibly meant for this
LL | //~^ ERROR cannot find function `is_directory`
LL | callback(path.as_ref();
| - un-closed delimiter
...
LL | } else {
| ^ unexpected token
| ^ incorrect close delimiter

error: expected one of `)`, `,`, `.`, `?`, or an operator, found `;`
--> $DIR/token-error-correct-3.rs:15:35
|
LL | callback(path.as_ref();
| ^ expected one of `)`, `,`, `.`, `?`, or an operator here

error[E0425]: cannot find function `is_directory` in this scope
--> $DIR/token-error-correct-3.rs:13:13
|
LL | if !is_directory(path.as_ref()) { //~ ERROR: cannot find function `is_directory`
LL | if !is_directory(path.as_ref()) {
| ^^^^^^^^^^^^ not found in this scope

error[E0308]: mismatched types
error[E0057]: this function takes 1 parameter but 2 parameters were supplied
--> $DIR/token-error-correct-3.rs:15:13
|
LL | fs::create_dir_all(path.as_ref()).map(|()| true) //~ ERROR: mismatched types
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- help: try adding a semicolon: `;`
| |
| expected (), found enum `std::result::Result`
|
= note: expected type `()`
found type `std::result::Result<bool, std::io::Error>`
LL | / callback(path.as_ref();
LL | | //~^ ERROR expected one of
LL | | //~| ERROR this function takes 1 parameter but 2 parameters were supplied
LL | | fs::create_dir_all(path.as_ref()).map(|()| true)
LL | | } else {
| |_________^ expected 1 parameter

error: aborting due to 4 previous errors

Some errors occurred: E0308, E0425.
For more information about an error, try `rustc --explain E0308`.
Some errors occurred: E0057, E0425.
For more information about an error, try `rustc --explain E0057`.

0 comments on commit 51d0e86

Please sign in to comment.