Do not complain about missing fn main()
in some cases
This commit is contained in:
parent
053a09529a
commit
454e2aa8c9
16 changed files with 50 additions and 116 deletions
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 4 previous errors
|
||||
|
||||
error: aborting due to 5 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`.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 previous error
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0601`.
|
||||
|
|
|
@ -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) {}
|
||||
|
||||
|
|
|
@ -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 3 previous errors
|
||||
|
||||
error: aborting due to 4 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`.
|
||||
|
|
|
@ -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`
|
||||
|
|
|
@ -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 3 previous errors
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0601`.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 2 previous errors
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0601`.
|
||||
|
|
Loading…
Add table
Reference in a new issue