Rustfmt and use lines with curly braces

Hey all,

I'm sure I could open a suggestion on Github somewhere if that's more appropriate, so do please let me know. But I wonder if I'm missing something, but it occurs to me that one of the features of rustfmt that seems to be missing is use line management.

By that, I mean that I can currently write:

use foo::bar::hello1;
use foo::bar::hello2;

I would have hoped/expected that rustfmt could transform that to be:

use foo::bar::{hello1, hello2};

Certainly, clippy already warns me if I do:

use foo::bar::{hello1};

But rustfmt isn't self-correcting in this regard.

Is this a "limitation" of rustfmt? If so, I'm happy to open something on Github if that's appropriate.

If not, and this has already been mentioned before, I apologise, but couldn't see anything from previous posts here, but am happy to stand corrected. :slight_smile:

Many thanks for you time.

Not entire sure how much this helps, but rest-analyzer can update your use statements with the curly-brace style with tab-completion.

I don't know of any lints for this, since I usually go through my diffs and make corrections by hand as needed. This might be a really good suggestion for the clippy issue tracker.

My guess would be that this is partially due to it not being obvious whether to replace

use foo::bar::hello1;
use foo::baz::hello2;


use foo::{bar::hello1, baz::hello2};

or, in the extreme case, just replace everything with one big use.

And thus it leaves the "should it be grouped" decision up to the coder.

TBH I'm surprised it doesn't remove the braces from use foo::bar::{hello1};, but then again it doesn't remove the parens from let x = (4); either, so I guess that's consistent?

(I generally don't use rustfmt unless forced.)

IIRC removing the braces can actually break things in a very specific situation. I forget what that situation is, though.

Hey @parasyte and @scottmcm

Thanks for your replies. This does make sense to me. For what it's worth, my coding environment is using neovim and rust treesitter.

I suppose my point here is that if I decide to run :RustFmt (which is provided via one of the plugins I use), then that operation ought to be a point-in-time analysis of what use lines I have right now, and how best to organise them. I'm currently unsure whether other development environments provide this or not.

It's perhaps a moot point though, since, as you say, you can identify the grouping manually -- I was more curious whether this was something which could occur automatically.

I'm on nightly and can confirm that rustfmt (default config) removes the meaningless braces, turning it into use foo::bar::hello1;.

I think doing this transformation would be problematic. You might have imports like this:

use std::{
    cell::{Cell, RefCell},
    collections::{BTreeMap, BTreeSet},
    sync::{Arc, Mutex, RwLock},

// use std::collections::{HashMap,HashSet};
use rustc_hash::{FxHashMap as HashMap, FxHashSet as HashSet};

(Actual example).
I want to be able to comment/uncomment the choice of HashMap, and I don't want rustfmt to interfere.

This option exists under imports_granularity. Try creating a rustfmt.toml in the project root with the contents imports_granularity="Crate" (or "Module" depending on which behaviour you want). It's a nightly option, but you can run rustfmt with nightly and keep using stable for the actual project by formatting with cargo +nightly fmt. If you usually format with something like the editor's format on save option, you can probably configure your editor to use this command as well. For example on vscode and rust-analyzer you can set

    "rust-analyzer.rustfmt.extraArgs": [

in your settings.json.

Unless you change the group_imports option, rustfmt will consider them separate import groups and won't merge them as long as there's a newline between them. Though it is true that if the commented line itself doesn't match the formatting rules, then it might be changed to, say,

use std::collections::HashMap;
use std::collections::HashSet;

with imports_granularity="Item" when it is uncommented.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.