about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_metadata/cstore_impl.rs2
-rw-r--r--src/librustc_passes/entry.rs9
-rw-r--r--src/libsyntax/parse/mod.rs4
-rw-r--r--src/libsyntax/parse/parser.rs13
-rw-r--r--src/libsyntax/parse/parser/diagnostics.rs5
-rw-r--r--src/libsyntax/sess.rs3
-rw-r--r--src/test/ui/parser-recovery-1.rs1
-rw-r--r--src/test/ui/parser-recovery-1.stderr26
-rw-r--r--src/test/ui/parser/issue-2354.rs7
-rw-r--r--src/test/ui/parser/issue-2354.stderr28
-rw-r--r--src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.rs3
-rw-r--r--src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.stderr25
-rw-r--r--src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.rs2
-rw-r--r--src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.stderr15
-rw-r--r--src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.rs1
-rw-r--r--src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr22
16 files changed, 50 insertions, 116 deletions
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index d942a19194a..cdf5da00606 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -440,7 +440,7 @@ impl cstore::CStore {
         let source_file = sess.parse_sess.source_map().new_source_file(source_name, def.body);
         let local_span = Span::with_root_ctxt(source_file.start_pos, source_file.end_pos);
         let (body, mut errors) = source_file_to_stream(&sess.parse_sess, source_file, None);
-        emit_unclosed_delims(&mut errors, &sess.diagnostic());
+        emit_unclosed_delims(&mut errors, &sess.parse_sess);
 
         // Mark the attrs as used
         let attrs = data.get_item_attrs(id.index, sess);
diff --git a/src/librustc_passes/entry.rs b/src/librustc_passes/entry.rs
index bf68807a0c2..66004719060 100644
--- a/src/librustc_passes/entry.rs
+++ b/src/librustc_passes/entry.rs
@@ -154,6 +154,14 @@ fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) -> Option<(De
 }
 
 fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) {
+    let sp = tcx.hir().krate().span;
+    if *tcx.sess.parse_sess.reached_eof.borrow() {
+        // There's an unclosed brace that made the parser reach `Eof`, we shouldn't complain about
+        // the missing `fn main()` then as it might have been hidden inside an unclosed block.
+        tcx.sess.delay_span_bug(sp, "`main` not found, but expected unclosed brace error");
+        return;
+    }
+
     // There is no main function.
     let mut err = struct_err!(tcx.sess, E0601,
         "`main` function not found in crate `{}`", tcx.crate_name(LOCAL_CRATE));
@@ -173,7 +181,6 @@ fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) {
     } else {
         String::from("consider adding a `main` function at the crate level")
     };
-    let sp = tcx.hir().krate().span;
     // The file may be empty, which leads to the diagnostic machinery not emitting this
     // note. This is a relatively simple way to detect that case and emit a span-less
     // note instead.
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 921c4ed0f0a..6d8ecdf805b 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -108,7 +108,7 @@ pub fn parse_stream_from_source_str(
         sess.source_map().new_source_file(name, source),
         override_span,
     );
-    emit_unclosed_delims(&mut errors, &sess.span_diagnostic);
+    emit_unclosed_delims(&mut errors, &sess);
     stream
 }
 
@@ -242,7 +242,7 @@ pub fn maybe_file_to_stream(
             err.buffer(&mut buffer);
             // Not using `emit_unclosed_delims` to use `db.buffer`
             for unmatched in unmatched_braces {
-                if let Some(err) = make_unclosed_delims_error(unmatched, &sess.span_diagnostic) {
+                if let Some(err) = make_unclosed_delims_error(unmatched, &sess) {
                     err.buffer(&mut buffer);
                 }
             }
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 5dbe4d95a85..e81d4573b73 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -148,8 +148,7 @@ pub struct Parser<'a> {
 
 impl<'a> Drop for Parser<'a> {
     fn drop(&mut self) {
-        let diag = self.diagnostic();
-        emit_unclosed_delims(&mut self.unclosed_delims, diag);
+        emit_unclosed_delims(&mut self.unclosed_delims, &self.sess);
     }
 }
 
@@ -1372,12 +1371,12 @@ impl<'a> Parser<'a> {
 
 crate fn make_unclosed_delims_error(
     unmatched: UnmatchedBrace,
-    handler: &errors::Handler,
+    sess: &ParseSess,
 ) -> Option<DiagnosticBuilder<'_>> {
     // `None` here means an `Eof` was found. We already emit those errors elsewhere, we add them to
     // `unmatched_braces` only for error recovery in the `Parser`.
     let found_delim = unmatched.found_delim?;
-    let mut err = handler.struct_span_err(unmatched.found_span, &format!(
+    let mut err = sess.span_diagnostic.struct_span_err(unmatched.found_span, &format!(
         "incorrect close delimiter: `{}`",
         pprust::token_kind_to_string(&token::CloseDelim(found_delim)),
     ));
@@ -1391,8 +1390,10 @@ crate fn make_unclosed_delims_error(
     Some(err)
 }
 
-pub fn emit_unclosed_delims(unclosed_delims: &mut Vec<UnmatchedBrace>, handler: &errors::Handler) {
+pub fn emit_unclosed_delims(unclosed_delims: &mut Vec<UnmatchedBrace>, sess: &ParseSess) {
+    *sess.reached_eof.borrow_mut() |= unclosed_delims.iter()
+        .any(|unmatched_delim| unmatched_delim.found_delim.is_none());
     for unmatched in unclosed_delims.drain(..) {
-        make_unclosed_delims_error(unmatched, handler).map(|mut e| e.emit());
+        make_unclosed_delims_error(unmatched, sess).map(|mut e| e.emit());
     }
 }
diff --git a/src/libsyntax/parse/parser/diagnostics.rs b/src/libsyntax/parse/parser/diagnostics.rs
index be1441d1c3f..fcf3b4c0aa8 100644
--- a/src/libsyntax/parse/parser/diagnostics.rs
+++ b/src/libsyntax/parse/parser/diagnostics.rs
@@ -1141,6 +1141,11 @@ impl<'a> Parser<'a> {
                  // Don't attempt to recover from this unclosed delimiter more than once.
                 let unmatched = self.unclosed_delims.remove(pos);
                 let delim = TokenType::Token(token::CloseDelim(unmatched.expected_delim));
+                if unmatched.found_delim.is_none() {
+                    // We encountered `Eof`, set this fact here to avoid complaining about missing
+                    // `fn main()` when we found place to suggest the closing brace.
+                    *self.sess.reached_eof.borrow_mut() = true;
+                }
 
                 // We want to suggest the inclusion of the closing delimiter where it makes
                 // the most sense, which is immediately after the last token:
diff --git a/src/libsyntax/sess.rs b/src/libsyntax/sess.rs
index 28a0868d5dd..323fe01f067 100644
--- a/src/libsyntax/sess.rs
+++ b/src/libsyntax/sess.rs
@@ -73,6 +73,8 @@ pub struct ParseSess {
     pub ambiguous_block_expr_parse: Lock<FxHashMap<Span, Span>>,
     pub injected_crate_name: Once<Symbol>,
     crate gated_spans: GatedSpans,
+    /// The parser has reached `Eof` due to an unclosed brace. Used to silence unnecessary errors.
+    pub reached_eof: Lock<bool>,
 }
 
 impl ParseSess {
@@ -101,6 +103,7 @@ impl ParseSess {
             ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
             injected_crate_name: Once::new(),
             gated_spans: GatedSpans::default(),
+            reached_eof: Lock::new(false),
         }
     }
 
diff --git a/src/test/ui/parser-recovery-1.rs b/src/test/ui/parser-recovery-1.rs
index 8126525c34f..21d36048e67 100644
--- a/src/test/ui/parser-recovery-1.rs
+++ b/src/test/ui/parser-recovery-1.rs
@@ -3,7 +3,6 @@
 // Test that we can recover from missing braces in the parser.
 
 trait Foo {
-//~^ ERROR `main` function not found
     fn bar() {
         let x = foo();
         //~^ ERROR cannot find function `foo` in this scope
diff --git a/src/test/ui/parser-recovery-1.stderr b/src/test/ui/parser-recovery-1.stderr
index ffe2b3322fc..83f8ef63c99 100644
--- a/src/test/ui/parser-recovery-1.stderr
+++ b/src/test/ui/parser-recovery-1.stderr
@@ -1,9 +1,8 @@
 error: this file contains an un-closed delimiter
-  --> $DIR/parser-recovery-1.rs:16:55
+  --> $DIR/parser-recovery-1.rs:15:55
    |
 LL | trait Foo {
    |           - un-closed delimiter
-LL |
 LL |     fn bar() {
    |              - this delimiter might not be properly closed...
 ...
@@ -14,36 +13,23 @@ LL | }
    |                                                       ^
 
 error: unexpected token: `;`
-  --> $DIR/parser-recovery-1.rs:13:15
+  --> $DIR/parser-recovery-1.rs:12:15
    |
 LL |     let x = y.;
    |               ^
 
 error[E0425]: cannot find function `foo` in this scope
-  --> $DIR/parser-recovery-1.rs:8:17
+  --> $DIR/parser-recovery-1.rs:7:17
    |
 LL |         let x = foo();
    |                 ^^^ not found in this scope
 
 error[E0425]: cannot find value `y` in this scope
-  --> $DIR/parser-recovery-1.rs:13:13
+  --> $DIR/parser-recovery-1.rs:12:13
    |
 LL |     let x = y.;
    |             ^ not found in this scope
 
-error[E0601]: `main` function not found in crate `parser_recovery_1`
-  --> $DIR/parser-recovery-1.rs:5:1
-   |
-LL | / trait Foo {
-LL | |
-LL | |     fn bar() {
-LL | |         let x = foo();
-...  |
-LL | |
-LL | | }
-   | |______________________________________________________^ consider adding a `main` function to `$DIR/parser-recovery-1.rs`
-
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0425, E0601.
-For more information about an error, try `rustc --explain E0425`.
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/parser/issue-2354.rs b/src/test/ui/parser/issue-2354.rs
index a14eb6e32fc..c4fc4716182 100644
--- a/src/test/ui/parser/issue-2354.rs
+++ b/src/test/ui/parser/issue-2354.rs
@@ -1,7 +1,4 @@
 fn foo() { //~ NOTE un-closed delimiter
-//~^ ERROR `main` function not found
-//~^^ NOTE main function must be defined
-//~^^^ NOTE you have one or more functions
   match Some(10) {
   //~^ NOTE this delimiter might not be properly closed...
       Some(y) => { panic!(); }
@@ -14,5 +11,5 @@ fn bar() {
     while (i < 1000) {}
 }
 
-fn main() {} //~ NOTE here is a function named `main`
-             //~ ERROR this file contains an un-closed delimiter
+fn main() {}
+//~ ERROR this file contains an un-closed delimiter
diff --git a/src/test/ui/parser/issue-2354.stderr b/src/test/ui/parser/issue-2354.stderr
index 038e3dcfa40..45199b02cb8 100644
--- a/src/test/ui/parser/issue-2354.stderr
+++ b/src/test/ui/parser/issue-2354.stderr
@@ -1,9 +1,8 @@
 error: this file contains an un-closed delimiter
-  --> $DIR/issue-2354.rs:18:66
+  --> $DIR/issue-2354.rs:15:53
    |
 LL | fn foo() {
    |          - un-closed delimiter
-...
 LL |   match Some(10) {
    |                  - this delimiter might not be properly closed...
 ...
@@ -11,28 +10,7 @@ LL | }
    | - ...as it matches this but it has different indentation
 ...
 LL |
-   |                                                                  ^
-
-error[E0601]: `main` function not found in crate `issue_2354`
-  --> $DIR/issue-2354.rs:1:1
-   |
-LL | / fn foo() {
-LL | |
-LL | |
-LL | |
-...  |
-LL | | fn main() {}
-LL | |
-   | |_________________________________________________________________^ the main function must be defined at the crate level (in `$DIR/issue-2354.rs`)
-   |
-note: here is a function named `main`
-  --> $DIR/issue-2354.rs:17:1
-   |
-LL | fn main() {}
-   | ^^^^^^^^^^^^
-   = note: you have one or more functions named `main` not defined at the crate level
-   = help: either move the `main` function definitions or attach the `#[main]` attribute to one of them
+   |                                                     ^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0601`.
diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.rs b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.rs
index 66f43889cec..8d89905909e 100644
--- a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.rs
+++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.rs
@@ -1,5 +1,4 @@
-impl T for () { //~ ERROR `main` function not found
-//~^ ERROR cannot find trait `T` in this scope
+impl T for () { //~ ERROR cannot find trait `T` in this scope
 
 fn foo(&self) {}
 
diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.stderr b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.stderr
index 52c00758b37..9bf54181a07 100644
--- a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.stderr
+++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.stderr
@@ -1,5 +1,5 @@
 error: this file contains an un-closed delimiter
-  --> $DIR/missing-close-brace-in-impl-trait.rs:13:53
+  --> $DIR/missing-close-brace-in-impl-trait.rs:12:53
    |
 LL | impl T for () {
    |               - un-closed delimiter
@@ -7,12 +7,12 @@ LL | impl T for () {
 LL |
    |                                                     ^
 
-error: expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`, `unsafe`, or `}`, found `trait`
-  --> $DIR/missing-close-brace-in-impl-trait.rs:6:1
+error: expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`, `unsafe`, or `}`, found keyword `trait`
+  --> $DIR/missing-close-brace-in-impl-trait.rs:5:1
    |
 LL | impl T for () {
    |               - unclosed delimiter
-...
+LL | 
 LL | fn foo(&self) {}
    |                 -
    |                 |
@@ -28,19 +28,6 @@ error[E0405]: cannot find trait `T` in this scope
 LL | impl T for () {
    |      ^ not found in this scope
 
-error[E0601]: `main` function not found in crate `missing_close_brace_in_impl_trait`
-  --> $DIR/missing-close-brace-in-impl-trait.rs:1:1
-   |
-LL | / impl T for () {
-LL | |
-LL | |
-LL | | fn foo(&self) {}
-...  |
-LL | | fn main() {}
-LL | |
-   | |____________________________________________________^ consider adding a `main` function to `$DIR/missing-close-brace-in-impl-trait.rs`
-
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0405, E0601.
-For more information about an error, try `rustc --explain E0405`.
+For more information about this error, try `rustc --explain E0405`.
diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.rs b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.rs
index 8f42897914a..5b716b1467c 100644
--- a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.rs
+++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.rs
@@ -1,4 +1,4 @@
-pub(crate) struct Bar<T> { //~ ERROR `main` function not found
+pub(crate) struct Bar<T> {
   foo: T,
 
 trait T { //~ ERROR expected identifier, found keyword `trait`
diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.stderr b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.stderr
index e0d5eb90aa1..ce399dbbf45 100644
--- a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.stderr
+++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.stderr
@@ -24,18 +24,5 @@ error: expected `:`, found `T`
 LL | trait T {
    |       ^ expected `:`
 
-error[E0601]: `main` function not found in crate `missing_close_brace_in_struct`
-  --> $DIR/missing-close-brace-in-struct.rs:1:1
-   |
-LL | / pub(crate) struct Bar<T> {
-LL | |   foo: T,
-LL | |
-LL | | trait T {
-...  |
-LL | |
-LL | | fn main() {}
-   | |_________________________________________________________________^ consider adding a `main` function to `$DIR/missing-close-brace-in-struct.rs`
-
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0601`.
diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.rs b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.rs
index 46b9cab66e9..79547195411 100644
--- a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.rs
+++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.rs
@@ -1,5 +1,4 @@
 trait T {
-//~^ ERROR `main` function not found in crate `missing_close_brace_in_trait`
     fn foo(&self);
 
 pub(crate) struct Bar<T>(); //~ ERROR expected one of
diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr
index 7de6c1d0cdd..4bfb4c1cb3a 100644
--- a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr
+++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr
@@ -1,5 +1,5 @@
 error: this file contains an un-closed delimiter
-  --> $DIR/missing-close-brace-in-trait.rs:11:66
+  --> $DIR/missing-close-brace-in-trait.rs:10:66
    |
 LL | trait T {
    |         - un-closed delimiter
@@ -7,12 +7,11 @@ LL | trait T {
 LL | fn main() {}
    |                                                                  ^
 
-error: expected one of `async`, `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found `pub`
-  --> $DIR/missing-close-brace-in-trait.rs:5:1
+error: expected one of `async`, `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found keyword `pub`
+  --> $DIR/missing-close-brace-in-trait.rs:4:1
    |
 LL | trait T {
    |         - unclosed delimiter
-LL |
 LL |     fn foo(&self);
    |                   -
    |                   |
@@ -22,18 +21,5 @@ LL |
 LL | pub(crate) struct Bar<T>();
    | ^^^ unexpected token
 
-error[E0601]: `main` function not found in crate `missing_close_brace_in_trait`
-  --> $DIR/missing-close-brace-in-trait.rs:1:1
-   |
-LL | / trait T {
-LL | |
-LL | |     fn foo(&self);
-LL | |
-...  |
-LL | |
-LL | | fn main() {}
-   | |_________________________________________________________________^ consider adding a `main` function to `$DIR/missing-close-brace-in-trait.rs`
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0601`.