-
Notifications
You must be signed in to change notification settings - Fork 892
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rustfmt deletes lines instead of detecting a syntax error #4126
Comments
what version of rustfmt are you using @jbaublitz?( |
Whoops! Sorry about that. |
No worries! Could you try the latest version (1.4.14) and see if there's any difference in behavior? rustfmt uses the rustc parser to get the AST for the input files, so the parsing behavior is really dependent on the version of the rustc parser that's in use by rustfmt. If the rustc parser errors, then rustfmt will bubble that error up accordingly. However, if the parser succeeds and is able to generate the AST, then rustfmt will use that AST to determine the corresponding formatting. |
Just confirmed that |
So far I'm not able to reproduce this. Could you run rustfmt in if you are running |
This may be related to the other code in the module outside of the example I pasted because I am getting:
when I reapply the incorrect syntax and run The repository is https://github.com/jbaublitz/neli and it is line number 128 on the branch |
Yikes! Thanks for the extra info @jbaublitz. I can reproduce this with Here's things working as expected using rustfmt $ rustc -Vv
rustc 1.44.0-nightly (7f3df5772 2020-04-16)
binary: rustc
commit-hash: 7f3df5772439eee1c512ed2eb540beef1124d236
commit-date: 2020-04-16
host: x86_64-unknown-linux-gnu
release: 1.44.0-nightly
LLVM version: 9.0
$ rustfmt --version
rustfmt 1.4.14-nightly (a5cb5d26 2020-04-14)
$ git branch
master
* v0.5.0-dev
$ rustfmt src/socket.rs --check
error: expected `{`, found keyword `if`
--> /home/caleb/dev/forks/neli/src/socket.rs:131:13
|
128 | ... if self.next_is_none.is_some() && if !n.nl_flags.contains(&NlmF::...
| -- this `if` expression has a condition, but no block
...
131 | ... if n.nl_type == NlTypeWrapper::Nlmsg(Nlmsg::Done) {
| ^^ expected `{`
|
help: try placing this code inside a block
|
131 | { if n.nl_type == NlTypeWrapper::Nlmsg(Nlmsg::Done) {
132 | return None;
133 | } }
|
but then with $ cargo fmt -- --check
Diff in /home/caleb/dev/forks/neli/src/socket.rs at line 125:
}
let next = self.stored.pop();
if let Some(ref n) = next {
- if self.next_is_none.is_some() && if !n.nl_flags.contains(&NlmF::Multi) {
- self.next_is_none = Some(true);
}
- if n.nl_type == NlTypeWrapper::Nlmsg(Nlmsg::Done) {
- return None;
}
}
next.map(Ok) |
A few things are happening here, will some require some changes to the mod resolver/non-inline module parsing (for example no longer disabling the parse session emitter after the initial crate parsing) |
@calebcartwright Excellent, thanks for looking into this! Given that I'm doing development on that branch, is it sufficient for you to keep a copy of the file/repo or do you have another suggestion? |
If you're asking if we need your source input as a reference then the answer is no, go ahead and do whatever you need with it! There's far simpler reproduction cases (basically any mod defined in an external file that has a recoverable parser error) that we'll put together as part of the test suites that'll accompany the fix for this. |
@calebcartwright Is this still reproducible with rustfmt from the master branch? |
@topecongiro - unfortunately yes it is. I've pushed a minimal reproducible example here where The problem comes from the changes made to incorporate the upstream parser/expansion changes (particularly that the parser no longer parses out-of-line mods), and I just didn't think about this use case. The formatting/mod resolver flow is still operating as if the pre-v651 version of the parser were in use, rustfmt/rustfmt-core/rustfmt-lib/src/formatting.rs Lines 73 to 99 in a9d7cd5
originally, if the parser successfully generated the AST for the crate, we were basically done with parsing, thus capturing the timing and disabling the emitter. rustfmt/rustfmt-core/rustfmt-lib/src/formatting.rs Lines 87 to 90 in a9d7cd5
however, parsing of out-of-line mods is now done as needed within the mod resolver as part of building out the mod/file mapping (initial step towards #3930). the parser is, of course, encountering a syntax error in this case, but because we've switched to a silent emitter that diagnostic message is being swallowed. And in the case of parsing a file as mod, we aren't checking the ParseSess for any parsing errors: rustfmt/rustfmt-core/rustfmt-lib/src/syntux/parser.rs Lines 185 to 192 in a9d7cd5
like we do when parsing the crate mod: rustfmt/rustfmt-core/rustfmt-lib/src/syntux/parser.rs Lines 220 to 236 in a9d7cd5
the mod resolver/mapping process is due for a refactor (#3930), but I'm not sure if it'd be easiest to try to fix the existing flow (by not disabling the emitter and checking for session errors when parsing the out-of-line mod files) or just go ahead with the refactor |
I think we should check for session errors in |
Code sample
This code sample had an error that I introduced while trying to fix a clippy error.
In particular, the line:
has two
if
s.Changes made by rustfmt
This is the diff I received when I ran rustfmt:
Expected behavior
I would hope that rustfmt would throw a syntax error instead of deleting the code. Will rustfmt typically proceed even if there is a syntax error in the code? I don't think I've ever run rustfmt on malformed code before.
The text was updated successfully, but these errors were encountered: