Skip to content
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 fails to format let-chain #5661

Closed
yanchith opened this issue Jan 16, 2023 · 5 comments
Closed

Rustfmt fails to format let-chain #5661

yanchith opened this issue Jan 16, 2023 · 5 comments

Comments

@yanchith
Copy link

yanchith commented Jan 16, 2023

I have a Rust source file with a couple of longer (~1000 lines) functions with deep nesting, and many comments.

I sometimes notice rustfmt give up and not modify some parts of the code, even when it's visually clear they should be modified (e.g. reindented). rustfmt --check doesn't report any errors.

Not sure how to repro publicly, because I can't share the code this happens on, but if I ever see it happen on an open codebase, I'll share.

Also let me know if you'd accept a patch fixing this, maybe I can debug in my spare time.

version: rustfmt 1.5.1-nightly (8a97b481 2022-12-22)
config:

group_imports = "StdExternalCrate"
hex_literal_case = "Lower"
imports_layout = "HorizontalVertical"
merge_derives = false
newline_style = "Unix"
use_field_init_shorthand = true
@ytmimi ytmimi added the needs-mcve needs a Minimal Complete and Verifiable Example label Jan 16, 2023
@ytmimi
Copy link
Contributor

ytmimi commented Jan 16, 2023

@yanchith Thanks for reaching out, but unless you can provide a code snippet to work off of then this isn't actionable. Additionally, what version of rustfmt are you ussing and are you using any non-default configuration options?

@yanchith
Copy link
Author

yanchith commented Jan 16, 2023

Thanks, I edited the version and config into the original post.

Yeah, I know this isn't great. I opened this hoping someone (possibly future me) will provide a repro case.

@ytmimi
Copy link
Contributor

ytmimi commented Jan 16, 2023

@yanchith can you take a section of code that isn't formatted and create a dummy example from it?

Given that this is deeply nested you're most likely running into issues with the max_width. You can try bumping the max_width to some sufficiently large number and then running rustfmt again. rustfmt is constrained to format your code within the max_width, and if it fails to do so then it will prevent formatting a given AST node.

If I had to guess, your issue is likely a duplicate of #3863, and if it's not related then the deeply nested nature of your program is the issue. Without seeing some code that reproduces the issue there isn't more I can do to help.

@yanchith
Copy link
Author

yanchith commented Jan 16, 2023

Serendipity! It just happened, in a section of code I managed to isolate. Pasting the following to a file and using the config above should not change a single line, even though it is clearly misformatted.

I also tried max_width up to 1000, and it didn't fix the issue.

fn rewind_level(level: &mut Level) {
    level.move_queue.clear();
    level.move_queue_speed_factor = 1.0;

    if have_player_caused_transaction(&level.transactions) {
        if let Some(snapshot) = level.history.pop_snapshot() {
            log::debug!("Rewinding one snapshot back with {} entities", snapshot.len(),);
            level.entities.clear();

            let mut manual = level.entities.manual_mode();
            for entity in snapshot {
                manual.insert(entity.id, entity);
            }
            manual.commit();
        } else {
            log::error!("Expected to find one snapshot to rewind, but found none");
        }
    } else {
        let mut success = false;
        if let Some(_) = level.history.pop_snapshot() {
            success = true;
        } else {
            log::error!("Expected to find two snapshots to rewind, but found none");
        }

        if success && let Some(snapshot) = level.history.pop_snapshot() {
                        log::debug!(
                            "Rewinding two snapshots back with {} entities",
                            snapshot.len(),
                        );

                        level.entities.clear();

                        let mut manual = level.entities.manual_mode();
                        for entity in snapshot {
                            manual.insert(entity.id, entity);
                        }
                        manual.commit();
                    } else {
                        log::error!("Expected to find two snapshots to rewind, but found just one");
                    }
    }
}

EDIT: the if success && let Some line seems to be causing this in this particular case, but I am pretty sure there's other cases, because I've been running into this since around 2018, when that if statement wasn't parsing yet.

@ytmimi
Copy link
Contributor

ytmimi commented Jan 16, 2023

Thanks for adding the code snippet. Yes, this issue is caused because rustfmt doesn't currently format let-chains. You can follow the tracking issue #5177 to be notified when support for the feature is added.

@ytmimi ytmimi closed this as not planned Won't fix, can't repro, duplicate, stale Jan 16, 2023
@ytmimi ytmimi removed the needs-mcve needs a Minimal Complete and Verifiable Example label Jan 16, 2023
@ytmimi ytmimi changed the title Rustfmt fails to format large functions with lots of nesting and comments Rustfmt fails to format let-chain Jan 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants