Rollup merge of #102350 - TaKO8Ki:incomplete-fn-in-struct-definition, r=fee1-dead
Improve errors for incomplete functions in struct definitions Given the following code: ```rust fn main() {} struct Foo { fn } ``` [playground](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=29139f870511f6918324be5ddc26c345) The current output is: ``` Compiling playground v0.0.1 (/playground) error: functions are not allowed in struct definitions --> src/main.rs:4:5 | 4 | fn | ^^ | = help: unlike in C++, Java, and C#, functions are declared in `impl` blocks = help: see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information error: could not compile `playground` due to previous error ``` In this case, rustc should suggest escaping `fn` to use it as an identifier.
This commit is contained in:
commit
6906e64c30
5 changed files with 44 additions and 16 deletions
|
@ -1753,18 +1753,24 @@ impl<'a> Parser<'a> {
|
|||
};
|
||||
// We use `parse_fn` to get a span for the function
|
||||
let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: true };
|
||||
if let Err(mut db) =
|
||||
self.parse_fn(&mut AttrVec::new(), fn_parse_mode, lo, &inherited_vis)
|
||||
{
|
||||
db.delay_as_bug();
|
||||
}
|
||||
match self.parse_fn(&mut AttrVec::new(), fn_parse_mode, lo, &inherited_vis) {
|
||||
Ok(_) => {
|
||||
let mut err = self.struct_span_err(
|
||||
lo.to(self.prev_token.span),
|
||||
&format!("functions are not allowed in {adt_ty} definitions"),
|
||||
);
|
||||
err.help("unlike in C++, Java, and C#, functions are declared in `impl` blocks");
|
||||
err.help(
|
||||
"unlike in C++, Java, and C#, functions are declared in `impl` blocks",
|
||||
);
|
||||
err.help("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information");
|
||||
err
|
||||
}
|
||||
Err(err) => {
|
||||
err.cancel();
|
||||
self.restore_snapshot(snapshot);
|
||||
self.expected_ident_found()
|
||||
}
|
||||
}
|
||||
} else if self.eat_keyword(kw::Struct) {
|
||||
match self.parse_item_struct() {
|
||||
Ok((ident, _)) => {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
struct Baz {
|
||||
inner : dyn fn ()
|
||||
//~^ ERROR expected `,`, or `}`, found keyword `fn`
|
||||
//~| ERROR functions are not allowed in struct definitions
|
||||
//~| ERROR expected identifier, found keyword `fn`
|
||||
//~| ERROR cannot find type `dyn` in this scope
|
||||
}
|
||||
|
||||
|
|
|
@ -4,16 +4,18 @@ error: expected `,`, or `}`, found keyword `fn`
|
|||
LL | inner : dyn fn ()
|
||||
| ^ help: try adding a comma: `,`
|
||||
|
||||
error: functions are not allowed in struct definitions
|
||||
error: expected identifier, found keyword `fn`
|
||||
--> $DIR/fn-field-parse-error-ice.rs:4:17
|
||||
|
|
||||
LL | struct Baz {
|
||||
| --- while parsing this struct
|
||||
LL | inner : dyn fn ()
|
||||
| ^^
|
||||
| ^^ expected identifier, found keyword
|
||||
|
|
||||
= help: unlike in C++, Java, and C#, functions are declared in `impl` blocks
|
||||
= help: see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information
|
||||
help: escape `fn` to use it as an identifier
|
||||
|
|
||||
LL | inner : dyn r#fn ()
|
||||
| ++
|
||||
|
||||
error[E0412]: cannot find type `dyn` in this scope
|
||||
--> $DIR/fn-field-parse-error-ice.rs:4:13
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
fn main() {}
|
||||
|
||||
struct S {
|
||||
fn: u8 //~ ERROR expected identifier, found keyword `fn`
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
error: expected identifier, found keyword `fn`
|
||||
--> $DIR/incomplete-fn-in-struct-definition.rs:4:5
|
||||
|
|
||||
LL | struct S {
|
||||
| - while parsing this struct
|
||||
LL | fn: u8
|
||||
| ^^ expected identifier, found keyword
|
||||
|
|
||||
help: escape `fn` to use it as an identifier
|
||||
|
|
||||
LL | r#fn: u8
|
||||
| ++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue