Style Guide: incorrect import normalisation that can not be employed by rustfmt
Nobody has claimed this yet.
- 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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