rust-lang / rust-lang/rust

Style Guide: incorrect import normalisation that can not be employed by rustfmt

Open
#158,356 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-resolve C-bug T-style
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

This is a followup issue on the rejected rustfmt PR rustfmt#6950.

The short description is that in the Rust Style Guide under import normalisation, there are 2 clauses:

Tools must make the following normalisations, recursively:

use a::self; -> use a;
...
use a::{b}; -> use a::b;

when these two clauses are combined (since tools must make the normalisations recursively), it follows that use a::{self}; must be normalised to use a;.

to achieve this exact feature I had sent a PR to rustfmt but it was rejected due to these normalisations producing semantically differing results. The linked issues are rustfmt#6129 and and rustfmt#3750. the gist is that the normalisation causes the std::vec::{self} module import to be normalised to std::vec, which imports the macro instead.

It's either the case that the Style Guide intended the tools to bring their own dependency resolution machinery (or import rust's internals directly), or this import case was overlooked. In any case, I don't think rustfmt currently employs the dependency resolution required for distinguishing between the std::vec module and the std::vec macros.

The decisions that led to the Normalisation clauses being added were made back in 2017, and the rustfmt maintainer ytmimi mentioned that

It's possible that these semantic differences have been addressed in new Rust language editions

This issue currently marks a discrepancy between how rustfmt handles import normalisation and how the official Rust style Guide declares tools need to act. Because there is a semantic difference between importing a module and importing a macro, it might be a stability hazard of some sort to even have {self} be normalised to a use segment with the parent segment's name (vec in std::vec::{self} case).

History

For convenience, i have traced the Style Guide normalization decisions back to their roots:

Can rustfmt definitively determine the equivalence?

They are always equivalent since paths in imports are always absolute

nrc's comment on import equivalence: https://github.com/rust-lang/style-team/issues/24#issuecomment-273633808

use foo::self -> use foo: https://github.com/rust-lang/style-team/issues/24#issuecomment-273637997
foo::{bar} to foo::bar: https://github.com/rust-lang/style-team/issues/24#issuecomment-273632135
first place where "Normalization" is explicitly laid out: https://github.com/rust-lang/style-team/issues/24#issuecomment-289649096

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the Style Guide's import normalisation section and the rejected rustfmt#6950 pull request, then review rustfmt#6129, rustfmt#3750, and the linked style-team discussion. Determine whether the {self} rule is valid for all relevant imports; done means the Style Guide and rustfmt behavior have an agreed, semantically safe resolution.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
documentation
Issue type
Documentation
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.