Skip to content

Commit

Permalink
Rollup merge of rust-lang#105502 - chenyukang:yukang/fix-105366-impl,…
Browse files Browse the repository at this point in the history
… r=estebank

Suggest impl in the scenario of typo with fn

Fixes rust-lang#105366
  • Loading branch information
matthiaskrgr authored Dec 14, 2022
2 parents 49b9907 + b70a869 commit c8fd654
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 2 deletions.
3 changes: 3 additions & 0 deletions compiler/rustc_error_messages/locales/en-US/parse.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -362,3 +362,6 @@ parse_fn_ptr_with_generics = function pointer types may not have generic paramet
parse_invalid_identifier_with_leading_number = expected identifier, found number literal
.label = identifiers cannot start with a number
parse_maybe_fn_typo_with_impl = you might have meant to write `impl` instead of `fn`
.suggestion = replace `fn` with `impl` here
8 changes: 8 additions & 0 deletions compiler/rustc_parse/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1221,3 +1221,11 @@ pub(crate) struct UnexpectedIfWithIf(
#[suggestion(applicability = "machine-applicable", code = " ", style = "verbose")]
pub Span,
);

#[derive(Diagnostic)]
#[diag(parse_maybe_fn_typo_with_impl)]
pub(crate) struct FnTypoWithImpl {
#[primary_span]
#[suggestion(applicability = "maybe-incorrect", code = "impl", style = "verbose")]
pub fn_span: Span,
}
20 changes: 18 additions & 2 deletions compiler/rustc_parse/src/parser/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::errors::{DocCommentDoesNotDocumentAnything, UseEmptyBlockNotSemi};
use super::diagnostics::{dummy_arg, ConsumeClosingDelim};
use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
use super::{AttrWrapper, FollowedByType, ForceCollect, Parser, PathStyle, TrailingToken};
use crate::errors::FnTypoWithImpl;
use rustc_ast::ast::*;
use rustc_ast::ptr::P;
use rustc_ast::token::{self, Delimiter, TokenKind};
Expand Down Expand Up @@ -2131,11 +2132,26 @@ impl<'a> Parser<'a> {
vis: &Visibility,
case: Case,
) -> PResult<'a, (Ident, FnSig, Generics, Option<P<Block>>)> {
let fn_span = self.token.span;
let header = self.parse_fn_front_matter(vis, case)?; // `const ... fn`
let ident = self.parse_ident()?; // `foo`
let mut generics = self.parse_generics()?; // `<'a, T, ...>`
let decl =
self.parse_fn_decl(fn_parse_mode.req_name, AllowPlus::Yes, RecoverReturnSign::Yes)?; // `(p: u8, ...)`
let decl = match self.parse_fn_decl(
fn_parse_mode.req_name,
AllowPlus::Yes,
RecoverReturnSign::Yes,
) {
Ok(decl) => decl,
Err(old_err) => {
// If we see `for Ty ...` then user probably meant `impl` item.
if self.token.is_keyword(kw::For) {
old_err.cancel();
return Err(self.sess.create_err(FnTypoWithImpl { fn_span }));
} else {
return Err(old_err);
}
}
};
generics.where_clause = self.parse_where_clause()?; // `where T: Ord`

let mut sig_hi = self.prev_token.span;
Expand Down
12 changes: 12 additions & 0 deletions src/test/ui/parser/issue-105366.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// run-rustfix

struct Foo;

impl From<i32> for Foo {
//~^ ERROR you might have meant to write `impl` instead of `fn`
fn from(_a: i32) -> Self {
Foo
}
}

fn main() {}
12 changes: 12 additions & 0 deletions src/test/ui/parser/issue-105366.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// run-rustfix

struct Foo;

fn From<i32> for Foo {
//~^ ERROR you might have meant to write `impl` instead of `fn`
fn from(_a: i32) -> Self {
Foo
}
}

fn main() {}
13 changes: 13 additions & 0 deletions src/test/ui/parser/issue-105366.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
error: you might have meant to write `impl` instead of `fn`
--> $DIR/issue-105366.rs:5:1
|
LL | fn From<i32> for Foo {
| ^^
|
help: replace `fn` with `impl` here
|
LL | impl From<i32> for Foo {
| ~~~~

error: aborting due to previous error

0 comments on commit c8fd654

Please sign in to comment.