Skip to content
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
f96cea0
stray
tshepang Apr 15, 2026
655bbe3
document missing import restrictions
tshepang Apr 15, 2026
f18f69d
be more formal
tshepang Apr 21, 2026
d02ce01
use normative language
tshepang May 6, 2026
f69dd3d
make "simple import" definition more clear, and fix one in main text
tshepang May 8, 2026
91092bf
use more simple sentences
tshepang May 8, 2026
2b56a0b
match existing style
tshepang May 8, 2026
9c70941
this fills a prior gap
tshepang May 13, 2026
215f85e
clarify rule
tshepang May 29, 2026
0f2c9c1
extra precision
tshepang May 29, 2026
d7e8007
the ranaming applies specifically to the path segment
tshepang May 29, 2026
2765077
remove the overspecification
tshepang May 29, 2026
857cd5e
re-word to match parent changes
tshepang Jun 2, 2026
29ca7f8
better grammar, maybe
tshepang Jun 2, 2026
542679c
fix case
tshepang Jun 12, 2026
c57f5c6
use better terminology
tshepang Jun 12, 2026
d6f50e9
there already exists a rule definiting what the 2 keywords mean
tshepang Jun 13, 2026
51e5a8d
this is a special term, so link to definition
tshepang Jun 13, 2026
106dab1
clarity
tshepang Jun 13, 2026
9e87caf
`self` is more special than the other path keywords
tshepang Jun 15, 2026
c2ca8e1
unwrap
tshepang Jun 15, 2026
a2fd6c1
simplify a rule
tshepang Jun 18, 2026
8724822
move import renaming rules closer together
tshepang Jun 18, 2026
8bc4ab2
update the super import rule
tshepang Jun 18, 2026
001ba74
global path: add a new rule and expand an existing one
tshepang Jun 19, 2026
f237bce
consistency
tshepang Jun 23, 2026
9170045
be more precise, and consistent
tshepang Jun 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion src/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,20 @@ Language changes in Rust 1.95.0
- Lints are outside the scope of the FLS.

- `Support importing path-segment keywords with renaming <https://github.com/rust-lang/rust/pull/146972>`_

- New paragraphs:

- :p:`fls_sUhnfV62HJrb`
- :p:`fls_QGdeRTe0H1Uc`
- :p:`fls_aam34hsRmKU2`

- Changed paragraphs:

- :p:`fls_2bkcn83smy2y`
- :p:`fls_iuzvtr3oax1o`
- :p:`fls_90hQvSh7Bfyg`
- :p:`fls_RUiFQ17bmRLt`

- `Stabilize ppc inline assembly <https://github.com/rust-lang/rust/pull/147996>`_

- The target is outside the scope of the FLS.
Expand All @@ -44,7 +58,10 @@ FLS corrections

Changed paragraph: :p:`fls_1941wid94hlg`

New paragraph: :p:`fls_CSuxTkwR96j9`
New paragraphs:

- :p:`fls_CSuxTkwR96j9`
- :p:`fls_LV94x3HlpBWk`

Language changes in Rust 1.94.0
-------------------------------
Expand Down
24 changes: 16 additions & 8 deletions src/entities-and-resolution.rst

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Target: src/entities-and-resolution.rst, Paths legality rules near fls_opn5n5t2mo3m.

I think this general path-position rule should also get the Rust 2021 use-path exception for braced/nesting-import final-self imports.

The ordinary path rule remains that self is only used at the beginning of a path. Use declarations have an additional self import behavior inside brace syntax: a final self in a nesting import imports the parent entity selected by the fully constructed import prefix. rust-lang/rust#146972 applies this use-path behavior to Rust 2018 and later, which covers the FLS Rust 2021 edition scope.

That keeps braced prefixed imports valid, including use crate::foo::bar::{self};, use crate::foo::bar::{self as name};, use crate::foo::{bar::foobar::quxbaz::self};, and use crate::foo::{bar::foobar::quxbaz::self as name};. It still rejects direct final-self paths such as use crate::foo::bar::self as name;, initial-self direct final paths such as use self::self as name;, and intermediate-self paths such as use foo::self::bar; and use a::{b::self::c};.

Replace fls_opn5n5t2mo3m with:

:dp:`fls_opn5n5t2mo3m`
If a :t:`path segment` is expressed as either :t:`keyword` ``crate``,
:t:`keyword` ``$crate``, or :t:`keyword` ``Self``, then the
:t:`path segment` shall be the first :t:`path segment` of a :t:`path`.
If a :t:`path segment` is expressed as :t:`keyword` ``self``, then the
:t:`path segment` shall be the first :t:`path segment` of a :t:`path`, except
that it may be the last :t:`path segment` of the :t:`simple path` of a
:t:`simple import` that appears in a :t:`nesting import`.

This keeps self::foo and use self as name; valid, keeps use a::b::{self as name}; and use a::{b::self as name}; valid for the use-import parent-entity case, and still rejects use a::b::self as name;, use self::self as name;, use a::{self::b};, and foo::self::bar.

I checked the following with rustc +1.95.0 --edition=2021:

// Valid.
use crate::foo::bar::{self as bar_alias};
use crate::foo::{bar::foobar::quxbaz::self};
use crate::foo::{bar::foobar::quxbaz::self as quxbaz_alias};
use {self::self as this_module};
use ::std::{vec::self as std_vec};

// Invalid.
use crate::foo::bar::self as bar_alias;
use self::self as this_module;
use a::{self::b};
use a::{b::self::c as bad};

Since this changes a general path legality paragraph, list fls_opn5n5t2mo3m as changed in the Rust 1.95 keyword-import changelog entry. The corresponding simple-import semantics should still get the fls_wRmvtgQkFA6w update from the simple-import thread so final-self nesting imports bring the parent entity selected by the import prefix into scope.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I actually like these suggestions, however fls_opn5n5t2mo3m should be split into two:

:dp:`fls_opn5n5t2mo3m`
If a :t:`path segment` is expressed as either :t:`keyword` ``crate``,
:t:`keyword` ``$crate``, or :t:`keyword` ``Self``, then the
:t:`path segment` shall be the first :t:`path segment` of a :t:`path`.

<new_FLS_ID>
If a :t:`path segment` is expressed as :t:`keyword` ``self``, then the
:t:`path segment` shall be the first :t:`path segment` of a :t:`path`, except
that it may be the last :t:`path segment` of the :t:`simple path` of a
:t:`simple import` that appears in a :t:`nesting import`.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

adjusted the wording for new rule slightly 9e87caf

Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ If a :t:`simple path` appears in a :t:`use import` and starts with a
:t:`path segment` expressed as either :t:`keyword` ``crate``, :t:`keyword`
``$crate``, :t:`keyword` ``self``, or :t:`keyword` ``super``, then the
:t:`path` shall be the :t:`simple path prefix` of a :t:`glob import` or a
:t:`nesting import`, or the :t:`simple path` of a :t:`simple import`.
:t:`nesting import`, or the :t:`path` of a :t:`simple import`.

:dp:`fls_cw006jhlboa`
If a :t:`simple path` appears in a :t:`use import` and starts with a
Expand Down Expand Up @@ -1049,9 +1049,7 @@ An :dt:`import path prefix` is the fully constructed :t:`path` prefix of a
the current :t:`use import`.

:dp:`fls_2bkcn83smy2y`
A :t:`simple import` is a :t:`use import` that brings all :t:`entities <entity>`
it refers to into scope, optionally with a different
:t:`name` than they are declared with by using a :t:`renaming`.
A :dt:`simple import` is a :t:`use import` that brings a :t:`simple path` into scope, optionally with a :t:`renaming`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this definition should stay entity/name based. A path is syntax; it does not get brought into scope. A use declaration brings selected entities into scope, usually by creating local name bindings, and as changes the local name for the imported entity. It can also use as _, where the imported entity is added to scope without a name.

That distinction matters for the new keyword-import restrictions because the meeting discussion resolved the renaming target as the imported entity, not the path or path segment. It also matters for final-self nesting imports: use a::{b::self}; imports the parent entity selected by the constructed import prefix, not an entity resolved through a literal final self member.

Suggested wording for both this paragraph and the glossary entry:

A :dt:`simple import` is a :t:`use import` that brings
:t:`entities <entity>` selected by its :t:`simple import path`, or by its
:t:`import path prefix` when its :t:`simple path` ends in :t:`keyword` ``self``
and it appears in a :t:`nesting import`, into :t:`scope`, either under their
declared :t:`[name]s`, under a different :t:`name` by using a :t:`renaming`, or
without a :t:`name` by using a :t:`renaming` with character underscore ``_``.

I think the empty-prefix and global-prefix cases should also be explicit. Rust 1.95.0 accepts both use {self as this_module}; and use {self::self as this_module};, where the prefix is local and empty. But use ::{self as root}; is different in Rust 2021: the prefix is the extern-prelude root and is rejected by the separate :: import restriction. I would update fls_WAA4WmohGu6T so empty local prefixes and global :: prefixes remain distinct:

:dp:`fls_WAA4WmohGu6T`
An :dt:`import path prefix` is the fully constructed :t:`path` prefix of a
:t:`use import`. An :t:`import path prefix` with no :t:`[path segment]s` and no
:t:`namespace qualifier` resolves to the current :t:`module`. An
:t:`import path prefix` that starts with :t:`namespace qualifier` ``::``
preserves that :t:`namespace qualifier` in the constructed prefix. An
:t:`import path prefix` for a given :t:`simple import` or :t:`glob import` is
constructed as follows:

#. :dp:`fls_IPYvldMqduf4`
   Start the :t:`import path prefix` as follows:

   * :dp:`fls_MOXId37fcNPY`
     If the :t:`use import` is a :t:`simple import`, then start with the
     :t:`simple import`'s :t:`simple path` :t:`path prefix`.

   * :dp:`fls_2UyFcB6Our1v`
     If the :t:`use import` is a :t:`glob import`, then start with the
     :t:`glob import`'s :t:`simple path prefix`.

   * :dp:`fls_irdKqoYzBM0M`
     If the :t:`use import` is a :t:`nesting import`, then start with the
     :t:`nesting import`'s :t:`simple path prefix`.

#. :dp:`fls_gAWsqibl4GLq`
   Then if the current :t:`use import` is the child of a :t:`nesting import`,
   prepend the :t:`nesting import`'s :t:`simple path prefix` to the
   :t:`import path prefix`. Repeat this step with the :t:`nesting import` as
   the current :t:`use import`.

Then I would update fls_wRmvtgQkFA6w so final-self simple imports inside brace syntax import the parent entity selected by the fully constructed prefix:

:dp:`fls_wRmvtgQkFA6w`
A :t:`simple import` brings :t:`[name]s` into :t:`scope` as follows:

* :dp:`fls_kz2Gij5wHXnl`
  If the :t:`simple import` appears in a :t:`nesting import` and the last
  :t:`path segment` of its :t:`simple path` is expressed as :t:`keyword`
  ``self``, then bring the :t:`entity` in :t:`type namespace` that the
  :t:`import path prefix` resolves to into :t:`scope`.

* :dp:`fls_ar03D5rxjzy0`
  If the :t:`simple path` is :t:`keyword` ``self``, then bring the containing
  :t:`module` into :t:`scope`.

* :dp:`fls_ce73bg0BqV1X`
  Otherwise bring all :t:`entities <entity>` that the :t:`simple import path`
  resolves to that are visible from the location of the
  :t:`simple import` into :t:`scope`.

This is the semantic counterpart to the path-position rule in the separate self path thread. It keeps use a::b::{self};, use a::{b::self};, and use ::std::{vec::self as std_vec}; valid, while direct final-self paths such as use a::b::self as name; remain rejected by the path-position rule.

I would also update fls_iQOgxNihUEr7 so the underscore-import rule matches this definition:

:dp:`fls_iQOgxNihUEr7`
An :t:`entity` imported by a :t:`simple import` subject to a :t:`renaming` with
character underscore ``_`` is added into :t:`scope` without a :t:`name`.

The changelog should list fls_WAA4WmohGu6T, fls_2bkcn83smy2y, fls_wRmvtgQkFA6w, fls_kz2Gij5wHXnl, fls_ar03D5rxjzy0, and fls_iQOgxNihUEr7 as changed; fls_yY58pFpkig9o as removed; and the :t:simple import glossary entry as updated. No extra paragraph ID should be needed if the :: prefix preservation wording stays folded into fls_WAA4WmohGu6T.


:dp:`fls_v3a6y2ze44v2`
A :t:`glob import` is a :t:`use import` that brings all :t:`entities <entity>`
Expand All @@ -1075,7 +1073,7 @@ A :t:`glob import` brings :t:`[name]s` into :t:`scope` as follows:

:dp:`fls_90hQvSh7Bfyg`
A :dt:`simple import path` is the :t:`path` constructed by appending the last
:t:`path segment` of a :t:`simple import`'s :t:`simple path` to the
:t:`path segment` of the :t:`path` of the :t:`simple import` to the
:t:`import path prefix`.

:dp:`fls_wRmvtgQkFA6w`
Expand Down Expand Up @@ -1116,7 +1114,7 @@ A :t:`glob import` outside of a :t:`nesting import` without a :t:`simple path
prefix` is rejected, but may still be consumed by :t:`[macro]s`.

:dp:`fls_RUiFQ17bmRLt`
A :t:`simple import` with a :t:`simple path` with a single :t:`path segment` of
A :t:`simple import` with a single :t:`path segment` of
keyword ``self`` shall be subject to the following:

* :dp:`fls_hv3xT2CjZuxc`
Expand All @@ -1135,6 +1133,18 @@ same :t:`namespace` but refer to different :t:`entities <entity>` if the
If two :t:`[glob import]s` import the same :t:`entity` under the same :t:`name`,
the :t:`visibility` of the :t:`name` is the most permissive one.

:dp:`fls_sUhnfV62HJrb`
When a :t:`path segment` expressed as :t:`keyword` ``crate`` or :t:`keyword` ``$crate`` is used to import the current :t:`crate`, the :t:`path segment` shall be subject to a :t:`renaming`.

:dp:`fls_QGdeRTe0H1Uc`
When a :t:`path segment` expressed as :t:`keyword` ``super`` is used to import a parent :t:`module`, the :t:`path segment` shall be subject to a :t:`renaming`.

@kirtchev-adacore kirtchev-adacore Jun 2, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

These are semantically incorrect. A path segment cannot be subject to a renaming, it is the simple import that is. The grammar is:

SimpleImport ::=
    SimplePath Renaming?

The renaming applies to the whole simple import, not to a particular path segment. Also look at my original suggestion:

When a :t:simple path segment expressed as :t:keyword super is used to import a parent :t:module, the :t:simple import shall be subject to a :t:renaming.

View changes since the review

@kirtchev-adacore kirtchev-adacore Jun 2, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

After a lengthy discussion with Tshepang on Meet, we determined that

  1. We may have a serious problem with out Path syntax.
  2. Assuming that we fix our Path syntax, Tshepang's original wording (path segment shall be subject to ...) is actually correct.

Tagging @traviscross and @ehuss to confirm / disprove.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

A few clarifications:

  1. We do not have a serious problem with our Path syntax, I simply misread the grammar.
  2. Based on the discussion on renamings, I propose the following wording:

When a :t:path segment expressed as :t:keyword super is used to import a parent :t:module, the imported :t:entity shall be subject to a :t:renaming.

Ditto for crate and $crate.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think Hristian's latest wording matches how I understand the meeting conclusion: the thing being renamed is the :t:entity imported by the related :t:simple import, not the textual :t:path segment. This is the FLS semantic model even though the grammar attaches Renaming? to SimpleImport. It also fits the existing FLS rule in fls_FILuR3pfwjw3, which already says an entity imported by a simple import subject to a renaming is brought into scope under the renamed name.

I would suggest replacing the current crate/$crate and super paragraphs along these lines. I would also suggest keeping $crate distinct enough to preserve fls_yrpem8vhxpr5, where $crate resolves to the crate that declares the macro being expanded. The Reference uses "current crate" in the macro-transcriber context, while the FLS already has a more precise macro-definition-crate model. The self restriction is covered in the separate self-import thread.

:dp:`fls_sUhnfV62HJrb`
When a :t:`path segment` expressed as :t:`keyword` ``crate`` is used to import
the current :t:`crate`, the :t:`entity` imported by the related
:t:`simple import` shall be subject to a :t:`renaming`.

:dp:`fls_61qKMG5tuv12`
When a :t:`path segment` expressed as :t:`keyword` ``$crate`` is used within a
:t:`macro transcriber` to import the :t:`crate` that declares the :t:`macro`
that is being expanded, the :t:`entity` imported by the related
:t:`simple import` shall be subject to a :t:`renaming`.

:dp:`fls_QGdeRTe0H1Uc`
When a :t:`path segment` expressed as :t:`keyword` ``super`` is used to import a
parent :t:`module`, the :t:`entity` imported by the related :t:`simple import`
shall be subject to a :t:`renaming`.

Use separate crate and $crate restriction paragraphs. That preserves the existing FLS $crate resolution rule in fls_yrpem8vhxpr5 and maps directly to the Reference anchors items.use.restrictions.crate-alias and items.use.restrictions.macro-crate-alias. The Rust 1.95 keyword-import changelog entry should list fls_sUhnfV62HJrb, fls_QGdeRTe0H1Uc, and fls_61qKMG5tuv12 as new paragraphs relative to the merge base.

@tshepang tshepang Jun 13, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

"the entity imported by the related simple import" is more wordy without adding precision, compared to "the imported entity". The word related also causes a pause in my mind, making we wonder what is related, that I could have missed something. It makes it a bit more confusing, making me adjust to the fact that it describes the import that is in the same sentence.

I do not agree that we need to use separate wording for crate and $crate, because the fact that the latter can only be used in macros should already be apparent elsewhere (fls_774uryecc2sx). I already consider "to import the current crate" as overspecification (and therefore confusing), because you can't do use crate as foo for anything but importing the current crate.

I made d6f50e9 to follow my thinking.


:dp:`fls_aam34hsRmKU2`
A :t:`simple path` consisting of namespace qualifier ``::`` followed by a :t:`path segment` expressed as :t:`keyword` ``self`` shall not be used.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This moves in the right direction compared with the earlier "external prelude cannot be imported" wording. I think it is still a bit too narrow for the surrounding FLS path model.

For Rust 2021, the Reference rule is two-part:

  • Leading :: resolves from the extern prelude and must be followed by the name of a crate.
  • The :: extern-prelude root itself cannot be imported, so use ::{self as root}; is rejected.

That preserves valid imports through extern-prelude crate names, such as use ::std::io; when std is in the external prelude, while rejecting direct root imports. The rustc tests for rust-lang/rust#146972 also reject keyword starts after ::, such as ::crate, ::super, and ::self.

As written, the FLS text only rejects ::self. The general FLS global path and keyword-segment rules should also reject ::crate, ::super, and ::$crate in Rust 2021 use paths.

Since FLS documents Rust 2021, I would split this into a general global-path legality rule plus the import-root restriction. The first paragraph follows the Reference path-qualifier rule for Rust 2018 and later and should live with the general Paths legality rules near the definition of :t:global path. The second follows the FLS import-prefix model and should stay with the Use Imports restrictions so it directly covers use ::{self as root};; the bare :: prefix there has no first path segment, so it needs a separate root-import rule.

This also depends on the import-prefix construction preserving the leading :: namespace qualifier. The simple-import thread updates fls_WAA4WmohGu6T so an empty prefix with no namespace qualifier resolves to the current module, while a prefix that starts with :: remains a global prefix. That keeps use {self as this_module}; distinct from use ::{self as root}; in the FLS model.

:dp:`fls_P6dFw89ZDKv2`
The first :t:`path segment` of a :t:`global path` shall be expressed as an
:t:`identifier` whose :t:`name` matches the :t:`name` of a
:t:`candidate external prelude entity`.

:dp:`fls_aam34hsRmKU2`
A :t:`simple import` whose :t:`import path prefix` consists only of
:t:`namespace qualifier` ``::`` and whose :t:`simple path` consists of a single
:t:`path segment` expressed as :t:`keyword` ``self`` shall not be used.

The first paragraph is what keeps use ::std::io; and use ::std::{io}; valid when std denotes a candidate external prelude entity, while rejecting keyword starts such as ::crate, ::super, and ::self in Rust 2021. The second paragraph captures the Reference's items.use.restrictions.extern-prelude rule for importing the bare extern-prelude root. The changelog should account for both fls_P6dFw89ZDKv2 and fls_aam34hsRmKU2 as new paragraphs relative to the merge base, and keep fls_WAA4WmohGu6T listed as changed for the import-prefix construction update.

@tshepang tshepang Jun 19, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

001ba74 expands fls_aam34hsRmKU2 suggestion, while removing "import path prefix" term since I don't quite understand the definition.

I also added fls_aam34hsRmKU2 as suggested, though I do not understand it well, particularly "candidate external prelude entity". That is, I don't understand the explanations given... maybe they need a rephrase.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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


:dp:`fls_LV94x3HlpBWk`
A :t:`simple import` shall not refer to :t:`[enum variant]s` through a :t:`type alias`.

.. rubric:: Examples

:dp:`fls_5dlnffim6fso`
Expand Down Expand Up @@ -1164,8 +1174,6 @@ The following is a selective import. The imported functions are
use outer_module::inner_module
{crate_visible_function, visible_function}

.. rubric:: Legality Rules

Comment thread
tshepang marked this conversation as resolved.
.. _fls_ydmnb7qnmzzq:

Shadowing
Expand Down
3 changes: 1 addition & 2 deletions src/glossary.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4099,8 +4099,7 @@ See :s:`SimpleCStringLiteral`.
simple import
^^^^^^^^^^^^^

A :dt:`simple import` is a :t:`use import` that binds a :t:`simple path` to a
local :t:`name` by using an optional :t:`renaming`.
A :dt:`simple import` is a :t:`use import` that brings a :t:`simple path` into scope, optionally with a :t:`renaming`.

See :s:`SimpleImport`.

Expand Down
Loading