Skip to content

Conversation

@tqwewe
Copy link
Contributor

@tqwewe tqwewe commented Oct 6, 2025

Fixes #6243 - Strange behavior for duplicate imports with imports_granularity="Module"

Problem

When using imports_granularity="Module", duplicate imports were being merged but not deduplicated, requiring multiple formatting passes to reach a stable state. This was inconsistent with other granularity settings which properly remove duplicates.

Solution

Added .dedup() calls after sorting import lists in three locations:

  • merge_rest() - when creating merged import lists
  • UseTree::normalize() - when normalizing nested imports
  • merge_use_trees_inner() - when merging use trees

This ensures duplicate imports are removed in a single formatting pass, matching the behavior of Crate and Item granularity settings.

Test Changes

Updated tests/target/multiple.rs to expect deduplicated imports. I believe the previous test was documenting the buggy behavior rather than the expected behavior.

Example

Before (unstable, requires 2 passes):

use risingwave_batch::executor::{BoxedExecutor, JoinType};
use risingwave_batch::executor::{BoxedExecutor, JoinType};
// First pass: {BoxedExecutor, BoxedExecutor, JoinType, JoinType}
// Second pass: {BoxedExecutor, JoinType}

After (stable, single pass):

use risingwave_batch::executor::{BoxedExecutor, JoinType};

Copy link
Member

@Manishearth Manishearth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In any situation where rustfmt produces a duplicate list, that resultant code will not compile. Thus this change cannot be breaking.

extern crate foo;

use std::cell::*;
use std::{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. Should we have this test at all? This original code won't compile, and now the use tree is much smaller. We should tweak this to import a lot of items

cc @calebcartwright if you have an idea as to what this test was doing before

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still think this should be fixed: let's change this to a test that imports a lot of different items.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rustfmt does still have to work on code that doesn't compile, provided it can still be parsed.

I'm not sure what the thinking was for making that distinction back in the day, but it made sense to me in the context of an inner dev-loop and format on save in editors

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, makes sense. We shouldn't have any stability around that but we should test it I guess.

borrow, borrow, boxed, boxed, boxed, boxed, boxed, boxed, boxed, boxed, boxed, boxed, char,
char, char, char, char, char, char, char, char, char,
};
use std::{self, any, ascii, borrow, boxed, char};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait, this is changing behavior without this flag.

However, this code is broken, so perhaps that's fine?

@Manishearth Manishearth merged commit ced5993 into rust-lang:master Nov 1, 2025
26 checks passed
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

Successfully merging this pull request may close these issues.

strange behavior for duplicate imports with imports_granularity="Module"

4 participants