Skip to content

document missing import restrictions#694

Open
tshepang wants to merge 25 commits into
mainfrom
tshepang/document-use-restrictions
Open

document missing import restrictions#694
tshepang wants to merge 25 commits into
mainfrom
tshepang/document-use-restrictions

Conversation

@tshepang

Copy link
Copy Markdown
Member

No description provided.

Comment thread src/entities-and-resolution.rst
@kirtchev-adacore kirtchev-adacore self-requested a review April 21, 2026 11:03
Comment thread src/entities-and-resolution.rst Outdated

@PLeVasseur PLeVasseur left a comment

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 comments are blocking because the PR currently adds only part of the upstream keyword-import model. In particular, the existing self and super legality rules still conflict with the new restriction paragraphs, so the FLS would remain internally inconsistent after merge. The remaining comments cover precision of the extern-prelude wording, preservation of the $crate distinction, and changelog classification.

View changes since this review

Comment thread src/entities-and-resolution.rst Outdated
the :t:`visibility` of the :t:`name` is the most permissive one.

:dp:`fls_sUhnfV62HJrb`
When :t:`keyword` ``crate`` or :t:`keyword` ``$crate`` is used to import the current :t:`crate`, a :t:`renaming` must be used to define the :t:`binding` name.

@PLeVasseur PLeVasseur Apr 22, 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.

This still looks incomplete relative to the upstream self-import change. Earlier FLS paragraphs still encode the pre rust-lang/rust#146972 behavior: fls_cw006jhlboa still requires a single-segment self use-path to appear only inside a nesting import, which rejects use self as name;, while fls_RUiFQ17bmRLt still allows unrenamed use self::{self}; when the import path prefix is non-empty.

After rust-lang/rust#146972, those move together: renamed current-module imports such as use self as name; are allowed, and unrenamed current-module imports like use self::{self}; are rejected.

Could this PR also update those earlier self paragraphs so the new restriction block and the older legality rules stay aligned? A minimal fix would be to loosen fls_cw006jhlboa for the renamed single-segment case and tighten fls_RUiFQ17bmRLt so the non-empty-prefix exception does not keep use self::{self}; valid.

Support:

@kirtchev-adacore kirtchev-adacore May 4, 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.

How about the following wording:

A :t:simple import where the first :t:path segment of its :t:simple path is either :t:keyword crate or :t:keyword $crate shall be subject to 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 made a blanket suggestion in #694 (comment).

@tshepang tshepang May 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.

Could this PR also update those earlier self paragraphs so the new restriction block and the older legality rules stay aligned? A minimal fix would be to loosen fls_cw006jhlboa for the renamed single-segment case and tighten fls_RUiFQ17bmRLt so the non-empty-prefix exception does not keep use self::{self}; valid.

am thinking of:

  • removing fls_cw006jhlboa because I don't quite understand it... somehow feels redundant
  • separating fls_RUiFQ17bmRLt into 2 separate rules, because "single path segment" is confusing

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.

For fls_cw006jhlboa, I think the cleanest route is to delete it and replace fls_RUiFQ17bmRLt with a semantic current-module import rule rather than a rule limited to a single-segment self simple path.

The cases I think we need to preserve are:

  1. Support importing path-segment keyword with renaming rust#146972 allows renamed current-module imports: use {self as this_module};, use self as this_module2;, use self::{self as this_module3};, and use {self::self as this_module4};.
  2. The same change still rejects unrenamed current-module imports: use {self};, use self;, use self::{self};, and use {self::self};.
  3. The post-rust-lang/rust#146972 Rust 2018-and-later use-path model keeps braced parent-entity imports valid in Rust 2021, including use a::b::{self};, use a::b::{self as name};, use a::{b::self};, and use a::{b::self as name};. Direct final-self paths such as use a::b::self as name; are still rejected by Rust 1.95.0 with E0429; the separate path-position comment updates fls_opn5n5t2mo3m so the final-self exception is limited to the braced/nesting-import form.

As written, fls_cw006jhlboa blocks the first group because it still requires a single-segment self use path to be part of a nesting import. As written, fls_RUiFQ17bmRLt leaves use self::{self}; looking valid because it has a non-empty import path prefix, and a single-segment-only replacement would still miss use {self::self};.

I would delete fls_cw006jhlboa. The replacement below keeps the current-module self import restriction where it belongs: on imports of the current module, not on every final-self parent-entity import. This does not affect the separate use self::*; glob-import restriction.

After deleting fls_cw006jhlboa, a copy-paste replacement for fls_RUiFQ17bmRLt could be as follows:

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

That keeps use a::b::{self}; and use a::{b::self}; valid, because the self there imports the parent entity a::b under its own name. It rejects use self::{self}; and use {self::self};, because those import the current module without a renaming. This requires the separate crate and super restriction paragraphs to use the imported-entity wording from the renaming thread; those paragraphs then reject unrenamed cases such as use crate::{self}; and use super::{self};, while still allowing parent-entity imports such as use crate::{m::self}; from a scope where that does not duplicate an existing name.

As a quick check with rustc +1.95.0 --edition=2021, use {self as this_module};, use self as this_module2;, use self::{self as this_module3};, and use {self::self as this_module4}; are valid, while use {self};, use self;, use self::{self};, and use {self::self}; remain invalid.

The Reference examples under items.use.restrictions.self-alias are a useful test matrix for this rule.

List fls_cw006jhlboa, fls_Pxc0Ts8Y7pfW, and fls_hv3xT2CjZuxc as removed, and keep fls_RUiFQ17bmRLt listed as changed. The corresponding simple-import semantics in fls_wRmvtgQkFA6w also need the 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
Member Author

Choose a reason for hiding this comment

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

I have simplified this to a2fd6c1

Comment thread src/entities-and-resolution.rst Outdated
When :t:`keyword` ``crate`` or :t:`keyword` ``$crate`` is used to import the current :t:`crate`, a :t:`renaming` must be used to define the :t:`binding` name.

:dp:`fls_QGdeRTe0H1Uc`
When :t:`keyword` ``super`` is used to import a parent :t:`module`, a :t:`renaming` must be used to define the :t:`binding` name.

@PLeVasseur PLeVasseur Apr 22, 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.

This new super rule still conflicts with the earlier path-legality rule. fls_7k88ypcgaoff currently allows a super segment only as the first segment or after another super, so the FLS still rejects self::super and self::super::super. Upstream now allows super after an initial self, and the Reference examples for this restriction explicitly include use self::super as parent3;.

Could this PR also relax fls_7k88ypcgaoff so super may follow an initial self, or otherwise carve out the same allowance for use paths, so the earlier path rules do not keep rejecting forms this paragraph is meant to document?

Support:

@kirtchev-adacore kirtchev-adacore May 4, 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.

How about the following wording:

A :t:simple import where any :t:path segment of its :t:simple path denotes :t:keyword super shall be subject to 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 made a blanket suggestion in #694 (comment).

@tshepang tshepang May 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.

@PLeVasseur fls_7k88ypcgaoff looks like it was wrong long before this PR, and I even think we should remove it... what do you think

@PLeVasseur PLeVasseur Jun 12, 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.

I think I would keep a revised fls_7k88ypcgaoff rather than remove it outright, because we still need a general path-legality rule that rejects non-leading super in paths such as foo::super, crate::super, and $crate::super; rust-lang/rust#146972 added the self::super allowance that now appears in the Reference path-qualifier rules.

The rustc implementation added this exact prefix check in build_reduced_graph_for_use_tree: the prefix before a super segment may contain super segments, plus self at position 0. The updated diagnostic says super can be used "in start position, after self, or after another super." rust-lang/reference#2136 then added use self::super as parent3; to the valid super import examples.

A direct FLS replacement could be:

:dp:`fls_7k88ypcgaoff`
If a :t:`path segment` is expressed as :t:`keyword` ``super``, then each
:t:`path segment` that precedes it in the :t:`path` shall be expressed as
:t:`keyword` ``super``, except that the first :t:`path segment` of the
:t:`path` may be expressed as :t:`keyword` ``self``.

This makes the intended cases valid:

use super as parent;
use super::{self as parent2};
use self::super as parent3;
use self::super::super as grandparent3;
use super::super as grandparent;
use super::super::{self as grandparent2};

It still rejects the cases rustc continues to reject, such as use foobar::super as name;, use self::foo::super as name;, use crate::super as name;, and use $crate::super as name;. The unchanged first-segment rule for crate, $crate, self, and Self continues to handle those keywords separately.

This intentionally does not handle ::super. This replacement depends on the global-path paragraph proposed in the :: thread; that paragraph rejects ::super for the separate Rust 2021 global-root reason. Since fls_7k88ypcgaoff is a general path legality paragraph, the changelog should record it as changed.

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.

Comment thread src/entities-and-resolution.rst Outdated
Comment thread src/entities-and-resolution.rst Outdated
the :t:`visibility` of the :t:`name` is the most permissive one.

:dp:`fls_sUhnfV62HJrb`
When :t:`keyword` ``crate`` or :t:`keyword` ``$crate`` is used to import the current :t:`crate`, a :t:`renaming` must be used to define the :t:`binding` name.

@PLeVasseur PLeVasseur Apr 22, 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.

$crate probably should not be folded into the same sentence as crate here. Earlier FLS text treats it as macro-specific in two ways: fls_774uryecc2sx only permits it within a macro transcriber, and fls_yrpem8vhxpr5 resolves it to the crate that defines the expanded macro. Grouping it under "used to import the current crate" makes $crate read like an ordinary spelling of crate, which is weaker than the current FLS model and the Reference's separate items.use.restrictions.macro-crate-alias rule.

Could this be split into separate crate and $crate restrictions, or reworded so the $crate half matches the existing FLS model and the Reference's separate items.use.restrictions.macro-crate-alias rule?

Support:

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.

I actually don't see any ambiguity here... both are indeed used to import the current crate, and any additional rules are written elsewhere (like the fact that $crate can only be used in macros), meaning that I find Reference text redundant.

Leaving it this bare makes it less confusing, in that if you say "When using $crate in a macro transcriber to import the current crate, you must use a renaming" makes it look like this is implied, "When using $crate in outside of macro transcriber to import the current crate, you need not use a renaming".

If it still feels dirty mixing them, I can create a separate paragraph, but that will have the exact same text, other than 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.

The distinction I am trying to preserve is not that the alias requirement is different for $crate; it is that the imported entity is described differently in the FLS model.

The existing FLS has two relevant rules:

  • fls_774uryecc2sx: a path starting with $crate appears only within a macro transcriber.
  • fls_yrpem8vhxpr5: $crate resolves to the crate that declares the macro that is being expanded.

So a combined crate/$crate paragraph that says both are used to import the current crate does not quite preserve the surrounding FLS text. In the macro case, $crate is intentionally definition-crate based. That distinction is also why the Reference keeps separate anchors for items.use.restrictions.crate-alias and items.use.restrictions.macro-crate-alias, even though the rules are adjacent and closely related. The Reference uses "current crate" in the macro-transcriber context, while the FLS source can preserve the more precise macro-definition-crate model it already has in fls_yrpem8vhxpr5.

I would suggest using the split wording from the renaming thread, with generated ID fls_61qKMG5tuv12 for the $crate paragraph:

: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`.

Use two paragraphs because they map cleanly to the two Reference anchors and avoid folding the macro-specific $crate rule into an ordinary crate sentence. List fls_sUhnfV62HJrb and fls_61qKMG5tuv12 as new paragraphs in the Rust 1.95 keyword-import changelog entry; fls_774uryecc2sx continues to provide the placement restriction for $crate.

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.

Comment thread src/changelog.rst Outdated
- :p:`fls_sUhnfV62HJrb`
- :p:`fls_QGdeRTe0H1Uc`
- :p:`fls_aam34hsRmKU2`
- :p:`fls_LV94x3HlpBWk`

@PLeVasseur PLeVasseur Apr 22, 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.

I rechecked the pre rust-lang/reference#2136 Reference snapshot, and the enum-variant-through-type-alias restriction was already present there as items.use.restrictions.variant. Since rust-lang/rust#146972 is specifically about keyword imports, adding fls_LV94x3HlpBWk under this Rust 1.95 language-change entry makes this look like an FLS correction rather than part of the 1.95 change itself.

Could this paragraph ID move out of the Support importing path-segment keywords with renaming entry and into the existing FLS corrections section instead, unless there is a stronger reason to tie it to rust-lang/rust#146972?

Support:

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.

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 part is addressed now: fls_LV94x3HlpBWk has been moved out of the Rust 1.95 Support importing path-segment keywords with renaming entry and into FLS corrections.

I would keep the thread unresolved until the remaining source edits are applied. With the recommended self/super/$crate/::/simple-import source shape, including the Rust 1.95.0 braced final-self cases such as use a::{b::self as name};, use the following base-relative changelog accounting.

The Rust 1.95 keyword-import entry should be:

  - New paragraphs:

    - :p:`fls_sUhnfV62HJrb`
    - :p:`fls_QGdeRTe0H1Uc`
    - :p:`fls_aam34hsRmKU2`
    - :p:`fls_P6dFw89ZDKv2`
    - :p:`fls_61qKMG5tuv12`

  - Changed paragraphs:

    - :p:`fls_opn5n5t2mo3m`
    - :p:`fls_WAA4WmohGu6T`
    - :p:`fls_2bkcn83smy2y`
    - :p:`fls_iuzvtr3oax1o`
    - :p:`fls_90hQvSh7Bfyg`
    - :p:`fls_wRmvtgQkFA6w`
    - :p:`fls_kz2Gij5wHXnl`
    - :p:`fls_ar03D5rxjzy0`
    - :p:`fls_iQOgxNihUEr7`
    - :p:`fls_RUiFQ17bmRLt`
    - :p:`fls_7k88ypcgaoff`

  - Removed paragraphs:

    - :p:`fls_cw006jhlboa`
    - :p:`fls_yY58pFpkig9o`
    - :p:`fls_Pxc0Ts8Y7pfW`
    - :p:`fls_hv3xT2CjZuxc`

  - Updated glossary entries:

    - :t:`simple import`

I trial-applied this accounting with the source snippets from the other comments and ./make.py --clear builds. I also expanded the Rust 1.95.0 edition-2021 test matrix to cover valid braced final-self imports, including use crate::foo::{bar::foobar::quxbaz::self};, and invalid direct/intermediate forms. This accounting assumes the :: import-prefix preservation wording is folded into the changed fls_WAA4WmohGu6T; if it is split into a separate paragraph, add that new paragraph to the same changelog entry.

I do not think any further changelog change is needed for the enum-variant-through-type-alias classification itself, but please verify that fls_LV94x3HlpBWk remains under FLS corrections and that the keyword-import entry is rechecked after the source-shape edits land.

Comment thread src/entities-and-resolution.rst Outdated
the :t:`visibility` of the :t:`name` is the most permissive one.

:dp:`fls_sUhnfV62HJrb`
When :t:`keyword` ``crate`` or :t:`keyword` ``$crate`` is used to import the current :t:`crate`, a :t:`renaming` must be used to define the :t:`binding` name.

@kirtchev-adacore kirtchev-adacore May 4, 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.

How about the following wording:

A :t:simple import where the first :t:path segment of its :t:simple path is either :t:keyword crate or :t:keyword $crate shall be subject to a :t:renaming.

Comment thread src/entities-and-resolution.rst Outdated
When :t:`keyword` ``crate`` or :t:`keyword` ``$crate`` is used to import the current :t:`crate`, a :t:`renaming` must be used to define the :t:`binding` name.

:dp:`fls_QGdeRTe0H1Uc`
When :t:`keyword` ``super`` is used to import a parent :t:`module`, a :t:`renaming` must be used to define the :t:`binding` name.

@kirtchev-adacore kirtchev-adacore May 4, 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.

How about the following wording:

A :t:simple import where any :t:path segment of its :t:simple path denotes :t:keyword super shall be subject to a :t:renaming.

Comment thread src/entities-and-resolution.rst Outdated
tshepang and others added 8 commits May 13, 2026 19:46
@tshepang tshepang force-pushed the tshepang/document-use-restrictions branch from 752f06e to 9c70941 Compare May 13, 2026 17:50
@rustbot

rustbot commented May 13, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

Comment thread src/entities-and-resolution.rst Outdated
Comment thread src/entities-and-resolution.rst Outdated
Comment thread src/entities-and-resolution.rst Outdated
tshepang and others added 4 commits May 29, 2026 11:30
Co-authored-by: Hristian Kirtchev <60669983+kirtchev-adacore@users.noreply.github.com>
Comment thread src/entities-and-resolution.rst Outdated
Comment thread src/entities-and-resolution.rst Outdated
tshepang and others added 2 commits June 2, 2026 15:35
Co-authored-by: Hristian Kirtchev <60669983+kirtchev-adacore@users.noreply.github.com>
Comment thread src/entities-and-resolution.rst Outdated
Comment on lines +1137 to +1140
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.

@PLeVasseur PLeVasseur left a comment

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 rechecked this against rust-lang/rust#146972, rust-lang/reference#2136, the current Reference text, and the FLS path/import model. The PR is pointed at the right upstream change. I think there are a few alignment points left where the new restriction paragraphs and the older path/import rules would otherwise disagree.

The main thing I am trying to preserve is that the new restriction paragraphs line up with the surrounding path/import rules. The current Reference text and the post-rust-lang/rust#146972 resolver model also rely on the surrounding self, super, $crate, and :: path rules lining up with the import restrictions. The FLS currently still has older rules that conflict with the new paragraphs, especially around use self as name;, use self::{self};, braced parent-entity imports such as use a::b::{self as name}; and use a::{b::self as name};, and use self::super as name;.

The remaining alignment points I see are:

  1. Use the meeting outcome/Hristian follow-up wording: the :t:entity imported by the related :t:simple import is subject to the :t:renaming, not the textual path segment.
  2. Update the existing self import rules so renamed current-module imports are accepted and unrenamed current-module imports remain rejected.
  3. Update fls_opn5n5t2mo3m for Rust 2021 use paths so self is still restricted in ordinary paths, while braced/nesting-import parent-entity imports such as use a::b::{self};, use a::b::{self as name};, use a::{b::self};, and use a::{b::self as name}; remain valid. Direct final-self paths such as use a::b::self as name; are still rejected by Rust 1.95.0 with E0429; rust-lang/rust#146972 leaves general support for self at the end of paths as future work.
  4. Update fls_7k88ypcgaoff so super is permitted to follow an initial self, while still rejecting non-leading super in paths such as foo::super or crate::super.
  5. Preserve the existing FLS distinction between crate and $crate; $crate resolves to the crate that declares the macro being expanded, not simply to the current crate in the same way as crate.
  6. Keep the Rust 2021 :: rule narrow: use ::std::io; remains valid, while importing the extern-prelude root itself is not valid. The constructed import-prefix model should preserve leading :: rather than treating a bare :: prefix as an empty local prefix.
  7. Avoid saying that a :t:simple import brings a path into scope. Paths are syntax; imports bring entities/names into scope. Also update the simple-import semantics for final-self nesting imports, make empty non-global import prefixes resolve to the current module, preserve global :: import prefixes, and update the existing underscore-renaming rule so it is not trait-specific.
  8. The enum-variant-through-type-alias changelog classification is addressed by moving fls_LV94x3HlpBWk to FLS corrections; the final changelog needs to account for the paragraph and glossary changes after this source-shape pass.

The changelog should account for IDs relative to the merge base rather than earlier PR revisions. With the source shape from the thread comments, fls_sUhnfV62HJrb, fls_QGdeRTe0H1Uc, fls_aam34hsRmKU2, fls_P6dFw89ZDKv2, and fls_61qKMG5tuv12 are new paragraphs; fls_opn5n5t2mo3m, fls_WAA4WmohGu6T, fls_2bkcn83smy2y, fls_iuzvtr3oax1o, fls_90hQvSh7Bfyg, fls_wRmvtgQkFA6w, fls_kz2Gij5wHXnl, fls_ar03D5rxjzy0, fls_iQOgxNihUEr7, fls_RUiFQ17bmRLt, and fls_7k88ypcgaoff are changed; fls_cw006jhlboa, fls_yY58pFpkig9o, fls_Pxc0Ts8Y7pfW, and fls_hv3xT2CjZuxc are removed; and the :t:simple import glossary entry is updated.

I trial-applied this source shape together, expanded the Rust 1.95.0 edition-2021 test matrix for braced final-self imports, and ./make.py --clear builds. The snippets should be copy-paste-ready as a combined patch.

I left the detailed suggestions in individual threads/comments; they are intended to be applied as one source shape.

View changes since this review

Comment thread src/entities-and-resolution.rst Outdated
Comment on lines +1137 to +1140
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`.

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.

Comment thread src/entities-and-resolution.rst Outdated
the :t:`visibility` of the :t:`name` is the most permissive one.

:dp:`fls_sUhnfV62HJrb`
When :t:`keyword` ``crate`` or :t:`keyword` ``$crate`` is used to import the current :t:`crate`, a :t:`renaming` must be used to define the :t:`binding` name.

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.

For fls_cw006jhlboa, I think the cleanest route is to delete it and replace fls_RUiFQ17bmRLt with a semantic current-module import rule rather than a rule limited to a single-segment self simple path.

The cases I think we need to preserve are:

  1. Support importing path-segment keyword with renaming rust#146972 allows renamed current-module imports: use {self as this_module};, use self as this_module2;, use self::{self as this_module3};, and use {self::self as this_module4};.
  2. The same change still rejects unrenamed current-module imports: use {self};, use self;, use self::{self};, and use {self::self};.
  3. The post-rust-lang/rust#146972 Rust 2018-and-later use-path model keeps braced parent-entity imports valid in Rust 2021, including use a::b::{self};, use a::b::{self as name};, use a::{b::self};, and use a::{b::self as name};. Direct final-self paths such as use a::b::self as name; are still rejected by Rust 1.95.0 with E0429; the separate path-position comment updates fls_opn5n5t2mo3m so the final-self exception is limited to the braced/nesting-import form.

As written, fls_cw006jhlboa blocks the first group because it still requires a single-segment self use path to be part of a nesting import. As written, fls_RUiFQ17bmRLt leaves use self::{self}; looking valid because it has a non-empty import path prefix, and a single-segment-only replacement would still miss use {self::self};.

I would delete fls_cw006jhlboa. The replacement below keeps the current-module self import restriction where it belongs: on imports of the current module, not on every final-self parent-entity import. This does not affect the separate use self::*; glob-import restriction.

After deleting fls_cw006jhlboa, a copy-paste replacement for fls_RUiFQ17bmRLt could be as follows:

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

That keeps use a::b::{self}; and use a::{b::self}; valid, because the self there imports the parent entity a::b under its own name. It rejects use self::{self}; and use {self::self};, because those import the current module without a renaming. This requires the separate crate and super restriction paragraphs to use the imported-entity wording from the renaming thread; those paragraphs then reject unrenamed cases such as use crate::{self}; and use super::{self};, while still allowing parent-entity imports such as use crate::{m::self}; from a scope where that does not duplicate an existing name.

As a quick check with rustc +1.95.0 --edition=2021, use {self as this_module};, use self as this_module2;, use self::{self as this_module3};, and use {self::self as this_module4}; are valid, while use {self};, use self;, use self::{self};, and use {self::self}; remain invalid.

The Reference examples under items.use.restrictions.self-alias are a useful test matrix for this rule.

List fls_cw006jhlboa, fls_Pxc0Ts8Y7pfW, and fls_hv3xT2CjZuxc as removed, and keep fls_RUiFQ17bmRLt listed as changed. The corresponding simple-import semantics in fls_wRmvtgQkFA6w also need the update from the simple-import thread so final-self nesting imports bring the parent entity selected by the import prefix into scope.

Comment thread src/entities-and-resolution.rst Outdated
When :t:`keyword` ``crate`` or :t:`keyword` ``$crate`` is used to import the current :t:`crate`, a :t:`renaming` must be used to define the :t:`binding` name.

:dp:`fls_QGdeRTe0H1Uc`
When :t:`keyword` ``super`` is used to import a parent :t:`module`, a :t:`renaming` must be used to define the :t:`binding` name.

@PLeVasseur PLeVasseur Jun 12, 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.

I think I would keep a revised fls_7k88ypcgaoff rather than remove it outright, because we still need a general path-legality rule that rejects non-leading super in paths such as foo::super, crate::super, and $crate::super; rust-lang/rust#146972 added the self::super allowance that now appears in the Reference path-qualifier rules.

The rustc implementation added this exact prefix check in build_reduced_graph_for_use_tree: the prefix before a super segment may contain super segments, plus self at position 0. The updated diagnostic says super can be used "in start position, after self, or after another super." rust-lang/reference#2136 then added use self::super as parent3; to the valid super import examples.

A direct FLS replacement could be:

:dp:`fls_7k88ypcgaoff`
If a :t:`path segment` is expressed as :t:`keyword` ``super``, then each
:t:`path segment` that precedes it in the :t:`path` shall be expressed as
:t:`keyword` ``super``, except that the first :t:`path segment` of the
:t:`path` may be expressed as :t:`keyword` ``self``.

This makes the intended cases valid:

use super as parent;
use super::{self as parent2};
use self::super as parent3;
use self::super::super as grandparent3;
use super::super as grandparent;
use super::super::{self as grandparent2};

It still rejects the cases rustc continues to reject, such as use foobar::super as name;, use self::foo::super as name;, use crate::super as name;, and use $crate::super as name;. The unchanged first-segment rule for crate, $crate, self, and Self continues to handle those keywords separately.

This intentionally does not handle ::super. This replacement depends on the global-path paragraph proposed in the :: thread; that paragraph rejects ::super for the separate Rust 2021 global-root reason. Since fls_7k88ypcgaoff is a general path legality paragraph, the changelog should record it as changed.

Comment thread src/entities-and-resolution.rst Outdated
the :t:`visibility` of the :t:`name` is the most permissive one.

:dp:`fls_sUhnfV62HJrb`
When :t:`keyword` ``crate`` or :t:`keyword` ``$crate`` is used to import the current :t:`crate`, a :t:`renaming` must be used to define the :t:`binding` name.

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.

The distinction I am trying to preserve is not that the alias requirement is different for $crate; it is that the imported entity is described differently in the FLS model.

The existing FLS has two relevant rules:

  • fls_774uryecc2sx: a path starting with $crate appears only within a macro transcriber.
  • fls_yrpem8vhxpr5: $crate resolves to the crate that declares the macro that is being expanded.

So a combined crate/$crate paragraph that says both are used to import the current crate does not quite preserve the surrounding FLS text. In the macro case, $crate is intentionally definition-crate based. That distinction is also why the Reference keeps separate anchors for items.use.restrictions.crate-alias and items.use.restrictions.macro-crate-alias, even though the rules are adjacent and closely related. The Reference uses "current crate" in the macro-transcriber context, while the FLS source can preserve the more precise macro-definition-crate model it already has in fls_yrpem8vhxpr5.

I would suggest using the split wording from the renaming thread, with generated ID fls_61qKMG5tuv12 for the $crate paragraph:

: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`.

Use two paragraphs because they map cleanly to the two Reference anchors and avoid folding the macro-specific $crate rule into an ordinary crate sentence. List fls_sUhnfV62HJrb and fls_61qKMG5tuv12 as new paragraphs in the Rust 1.95 keyword-import changelog entry; fls_774uryecc2sx continues to provide the placement restriction for $crate.

Comment thread src/changelog.rst Outdated
- :p:`fls_sUhnfV62HJrb`
- :p:`fls_QGdeRTe0H1Uc`
- :p:`fls_aam34hsRmKU2`
- :p:`fls_LV94x3HlpBWk`

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 part is addressed now: fls_LV94x3HlpBWk has been moved out of the Rust 1.95 Support importing path-segment keywords with renaming entry and into FLS corrections.

I would keep the thread unresolved until the remaining source edits are applied. With the recommended self/super/$crate/::/simple-import source shape, including the Rust 1.95.0 braced final-self cases such as use a::{b::self as name};, use the following base-relative changelog accounting.

The Rust 1.95 keyword-import entry should be:

  - New paragraphs:

    - :p:`fls_sUhnfV62HJrb`
    - :p:`fls_QGdeRTe0H1Uc`
    - :p:`fls_aam34hsRmKU2`
    - :p:`fls_P6dFw89ZDKv2`
    - :p:`fls_61qKMG5tuv12`

  - Changed paragraphs:

    - :p:`fls_opn5n5t2mo3m`
    - :p:`fls_WAA4WmohGu6T`
    - :p:`fls_2bkcn83smy2y`
    - :p:`fls_iuzvtr3oax1o`
    - :p:`fls_90hQvSh7Bfyg`
    - :p:`fls_wRmvtgQkFA6w`
    - :p:`fls_kz2Gij5wHXnl`
    - :p:`fls_ar03D5rxjzy0`
    - :p:`fls_iQOgxNihUEr7`
    - :p:`fls_RUiFQ17bmRLt`
    - :p:`fls_7k88ypcgaoff`

  - Removed paragraphs:

    - :p:`fls_cw006jhlboa`
    - :p:`fls_yY58pFpkig9o`
    - :p:`fls_Pxc0Ts8Y7pfW`
    - :p:`fls_hv3xT2CjZuxc`

  - Updated glossary entries:

    - :t:`simple import`

I trial-applied this accounting with the source snippets from the other comments and ./make.py --clear builds. I also expanded the Rust 1.95.0 edition-2021 test matrix to cover valid braced final-self imports, including use crate::foo::{bar::foobar::quxbaz::self};, and invalid direct/intermediate forms. This accounting assumes the :: import-prefix preservation wording is folded into the changed fls_WAA4WmohGu6T; if it is split into a separate paragraph, add that new paragraph to the same changelog entry.

I do not think any further changelog change is needed for the enum-variant-through-type-alias classification itself, but please verify that fls_LV94x3HlpBWk remains under FLS corrections and that the keyword-import entry is rechecked after the source-shape edits land.

Comment thread src/entities-and-resolution.rst Outdated
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`.

: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.

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.

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

tshepang added 4 commits June 12, 2026 19:48
This matches fls_FILuR3pfwjw3, where the term "entity" is used to refer
to the thing brought into scope.
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.

5 participants