Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions exts/ferrocene_spec/definitions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@ def apply(self):
)
)
else:
if node["ref_kind"] == "term":
doc = node["ref_source_doc"]
text = node["ref_text"]
print(f"warn: document={doc} has dangling term, {text}")
new = nodes.inline(
"",
"",
Expand Down
40 changes: 40 additions & 0 deletions src/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,46 @@ with the change that has been applied due to it.
FLS maintenance
---------------

- Paragraphs added or changed to ensure all glossary terms are also found in the main text:

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 maintenance summary feels stronger than the current state of the PR. The branch still leaves live references to removed glossary terms at src/glossary.rst:945, 1255, and 3537, so the claim here seems too strong as written. This block also does not appear to cover the full set of related edits: fls_rnty1c8l5495 (src/macros.rst:28) and fls_aie0tr62vhw5 (src/types-and-traits.rst:1767) are not listed here, and fls_kv533rntni1x (src/patterns.rst:91) is only mentioned earlier in the changelog. Could we narrow the wording here, or wait to add the stronger summary until those dangling references are resolved?

@tshepang tshepang Apr 23, 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.

I would not want the PR to be accepted until the maintenace summary claim is reached

the example you gave are mere wording fixes/adjustments, and therefore do not need to be accounted for in the changelog


- :p:`fls_BBz4Iy7AeaU4`
- :p:`fls_cxNAtLSLjqbQ`
- :p:`fls_hyi2jnp38v1n`
- :p:`fls_twC8XhwbI60x`
- :p:`fls_9bp4cKSfW9A0`
- :p:`fls_Odh6Z7ivD1U4`
- :p:`fls_FG0EmVgrDUDq`

- Paragraphs changed to avoid referencing indirect terms:

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 PR shows a potential process gap: unresolved :t: fallout can pass CI (for example src/glossary.rst:945, src/glossary.rst:1255, src/glossary.rst:3537, and wrapped ``:t:crate\nroot``` at src/entities-and-resolution.rst:953-954`). Since this tracking effort depends on moving terms into chapter `:dt:` definitions safely, we should have an automated guardrail. Could we track a dedicated lint or CI check that verifies every `:t:` resolves to a live `:dt:` definition, including wrapped forms, rather than relying on manual cleanup?

Details:

  • Missing :t: refs do not become Sphinx warnings in this repo.
  • In exts/ferrocene_spec/definitions/init.py:136-158, if a definition target is missing, the extension does this:
    • it does not log a warning
    • it does not create a broken link
    • it replaces the role with plain inline text and adds CSS class spec-missing-ref
  • For term refs specifically, exts/ferrocene_spec/definitions/terms.py:37-38 returns just nodes.Text(text).
  • The theme then only colors that text as an error in HTML: themes/fls/static/fls.css:761-763.

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.


- :p:`fls_xmgcdw9yhb55`
- :p:`fls_yeh6mvyvb4dp`
- :p:`fls_657knnsobdyu`
- :p:`fls_m942dwwmr2cl`
- :p:`fls_np33oqrz33mp`
- :p:`fls_atdpr8be2o2r`
- :p:`fls_fbgwb3pdfgz`
- :p:`fls_8tbxq95x06yt`
- :p:`fls_9oy9zo3x3fy3`
- :p:`fls_pdgj2xekdead`
- :p:`fls_4uoi6k8r7mvc`
- :p:`fls_fjaz4m90cagr`
- :p:`fls_eesn9kuylim`
- :p:`fls_ijfmnnrdlu8n`
- :p:`fls_6x7j9x354pkb`
- :p:`fls_h2cpbz2t74hy`
- :p:`fls_whj50spxz3bh`
- :p:`fls_d1cxq1zbt5fq`
- :p:`fls_48i245an2449`
- :p:`fls_69wr03rt0ali`
- :p:`fls_9d970yfwmj2d`
- :p:`fls_p9687v3xckps`
- :p:`fls_8j408kckzzud`
- :p:`fls_mdejdc0nNgyO`
- :p:`fls_WUCvCauUCmsD`
- :p:`fls_5SVthCNZBcVS`
- :p:`fls_SonodAQVL5J4`

- Remove the term "indirection", and associated derivatives

Changed glossary entries:
Expand Down
8 changes: 1 addition & 7 deletions src/entities-and-resolution.rst
Original file line number Diff line number Diff line change
Expand Up @@ -948,13 +948,7 @@ The :dt:`core prelude` is a :t:`prelude` that brings :t:`in scope` of every
:std:`core::prelude::rust_2021` :t:`module`.

:dp:`fls_atvnwly4w8g2`
An :dt:`external prelude` is a :t:`prelude` that brings :t:`in scope` of the
:t:`crate root module` the :t:`entities <entity>` of the :t:`[crate]s` imported
using external :t:`[crate import]s` or supplied by a tool. If the external
:t:`crate import` uses a :t:`renaming`, then the :t:`identifier` of the
:t:`renaming` is instead added to the :t:`external prelude`. The core
:t:`crate` is always added to the :t:`external prelude` unless the :t:`crate
root` is subject to :t:`attribute` ``no_core``.
An :dt:`external prelude` is a :t:`prelude` that brings :t:`in scope` of the :t:`crate root module` the :t:`entities <entity>` of the :t:`[crate]s` imported using external :t:`[crate import]s` or supplied by a tool. If the external :t:`crate import` uses a :t:`renaming`, then the :t:`identifier` of the :t:`renaming` is instead added to the :t:`external prelude`. The core :t:`crate` is always added to the :t:`external prelude` unless the :t:`crate root module` is subject to :t:`attribute` ``no_core``.

:dp:`fls_pbc7ktlu0pl`
The :dt:`language prelude` is a :t:`prelude` that brings :t:`in scope` of every
Expand Down
49 changes: 26 additions & 23 deletions src/expressions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2606,68 +2606,68 @@ is used in the calculation of a :t:`compound assignment expression`.
An :t:`assigned operand` shall denote a :t:`mutable assignee expression`.

:dp:`fls_xmgcdw9yhb55`
The :t:`type` of a :t:`compound assignment` is the :t:`unit type`.
The :t:`type` of a :t:`compound assignment expression` is the :t:`unit type`.

:dp:`fls_yeh6mvyvb4dp`
The :t:`value` of a :t:`compound assignment` is the :t:`unit value`.
The :t:`value` of a :t:`compound assignment expression` is the :t:`unit value`.

:dp:`fls_657knnsobdyu`
The :t:`type` of the :t:`assigned operand` of an :t:`addition assignment` shall
The :t:`type` of the :t:`assigned operand` of an :t:`addition assignment expression` shall
implement the :std:`core::ops::AddAssign` trait where the type of the right
operand is the trait implementation type parameter.

:dp:`fls_m942dwwmr2cl`
The :t:`type` of the :t:`assigned operand` of a :t:`bit and assignment` shall
The :t:`type` of the :t:`assigned operand` of a :t:`bit and assignment expression` shall
implement the :std:`core::ops::BitAndAssign` :t:`trait` where the :t:`type` of
the :t:`modifying operand` is the :t:`trait implementation` :t:`type parameter`.

:dp:`fls_np33oqrz33mp`
The :t:`type` of the :t:`assigned operand` of a :t:`bit or assignment` shall
The :t:`type` of the :t:`assigned operand` of a :t:`bit or assignment expression` shall
implement the :std:`core::ops::BitOrAssign` :t:`trait` where the :t:`type` of
the :t:`modifying operand` is the :t:`trait implementation` :t:`type parameter`.

:dp:`fls_atdpr8be2o2r`
The :t:`type` of the :t:`assigned operand` of a :t:`bit xor assignment` shall
The :t:`type` of the :t:`assigned operand` of a :t:`bit xor assignment expression` shall
implement the :std:`core::ops::BitXorAssign` :t:`trait` where the :t:`type` of
the :t:`modifying operand` is the :t:`trait implementation` :t:`type parameter`.

:dp:`fls_fbgwb3pdfgz`
The :t:`type` of the :t:`assigned operand` of a :t:`division assignment` shall
The :t:`type` of the :t:`assigned operand` of a :t:`division assignment expression` shall
implement the :std:`core::ops::DivAssign` :t:`trait` where the :t:`type` of the
:t:`modifying operand` is the :t:`trait implementation` :t:`type parameter`.

:dp:`fls_8tbxq95x06yt`
The :t:`type` of the :t:`assigned operand` of a :t:`multiplication assignment`
The :t:`type` of the :t:`assigned operand` of a :t:`multiplication assignment expression`
shall implement the :std:`core::ops::MulAssign` :t:`trait` where the :t:`type`
of the :t:`modifying operand` is the :t:`trait implementation`
:t:`type parameter`.

:dp:`fls_9oy9zo3x3fy3`
The :t:`type` of the :t:`assigned operand` of a :t:`remainder assignment` shall
The :t:`type` of the :t:`assigned operand` of a :t:`remainder assignment expression` shall
implement the :std:`core::ops::RemAssign` :t:`trait` where the :t:`type` of the
:t:`modifying operand` is the :t:`trait implementation` :t:`type parameter`.

:dp:`fls_pdgj2xekdead`
The :t:`type` of the :t:`assigned operand` of a :t:`shift left assignment` shall
The :t:`type` of the :t:`assigned operand` of a :t:`shift left assignment expression` shall
implement the :std:`core::ops::ShlAssign` :t:`trait` where the :t:`type` of the
:t:`modifying operand` is the :t:`trait implementation` :t:`type parameter`.

:dp:`fls_4uoi6k8r7mvc`
The :t:`type` of the :t:`assigned operand` of a :t:`shift right assignment`
The :t:`type` of the :t:`assigned operand` of a :t:`shift right assignment expression`
shall implement the :std:`core::ops::ShrAssign` :t:`trait` where the :t:`type`
of the :t:`modifying operand` is the :t:`trait implementation`
:t:`type parameter`.

:dp:`fls_fjaz4m90cagr`
The :t:`type` of the :t:`assigned operand` of a :t:`subtraction assignment`
The :t:`type` of the :t:`assigned operand` of a :t:`subtraction assignment expression`
shall implement the :std:`core::ops::SubAssign` :t:`trait` where the :t:`type`
of the :t:`modifying operand` is the :t:`trait implementation`
:t:`type parameter`.

.. rubric:: Dynamic Semantics

:dp:`fls_eesn9kuylim`
The :t:`evaluation` of a :t:`compound assignment` proceeds as follows:
The :t:`evaluation` of a :t:`compound assignment expression` proceeds as follows:

#. :dp:`fls_4nnqz4etisgw`
If the :t:`[type]s` of both :t:`[operand]s` are :t:`[integer type]s` or :t:`[floating-point type]s`, then
Expand All @@ -2694,52 +2694,52 @@ The :t:`evaluation` of a :t:`compound assignment` proceeds as follows:
The appropriate :t:`function` is invoked as indicated below.

:dp:`fls_ijfmnnrdlu8n`
For an :t:`addition assignment`,
For an :t:`addition assignment expression`,
``core::ops::AddAssign::add_assign(&mut assigned_operand, modifying_operand)``
is invoked.

:dp:`fls_6x7j9x354pkb`
For a :t:`bit and assignment`,
For a :t:`bit and assignment expression`,
``core::ops::BitAndAssign::bitand_assign(&mut assigned_operand, modifying_operand)``
is invoked.

:dp:`fls_h2cpbz2t74hy`
For a :t:`bit or assignment`,
For a :t:`bit or assignment expression`,
``core::ops::BitOrAssign::bitor_assign(&mut assigned_operand, modifying_operand)``
is invoked.

:dp:`fls_whj50spxz3bh`
For a :t:`bit xor assignment`,
For a :t:`bit xor assignment expression`,
``core::ops::BitXorAssign::bitxor_assign(&mut assigned_operand, modifying_operand)``
is invoked.

:dp:`fls_d1cxq1zbt5fq`
For a :t:`division assignment`,
For a :t:`division assignment expression`,
``core::ops::DivAssign::div_assign(&mut assigned_operand, modifying_operand)``
is invoked.

:dp:`fls_48i245an2449`
For a :t:`multiplication assignment`,
For a :t:`multiplication assignment expression`,
``core::ops::MulAssign::mul_assign(&mut assigned_operand, modifying_operand)``
is invoked.

:dp:`fls_69wr03rt0ali`
For a :t:`remainder assignment`,
For a :t:`remainder assignment expression`,
``core::ops::RemAssign::rem_assign(&mut assigned_operand, modifying_operand)``
is invoked.

:dp:`fls_9d970yfwmj2d`
For a :t:`shift left assignment`,
For a :t:`shift left assignment expression`,
``core::ops::ShlAssign::shl_assign(&mut assigned_operand, modifying_operand)``
is invoked.

:dp:`fls_p9687v3xckps`
For a :t:`shift right assignment`,
For a :t:`shift right assignment expression`,
``core::ops::ShrAssign::shr_assign(&mut assigned_operand, modifying_operand)``
is invoked.

:dp:`fls_8j408kckzzud`
For a :t:`subtraction assignment`,
For a :t:`subtraction assignment expression`,
``core::ops::SubAssign::sub_assign(&mut assigned_operand, modifying_operand)``
is invoked.

Expand Down Expand Up @@ -3562,6 +3562,9 @@ The :t:`evaluation` of a :t:`method call expression` proceeds as follows:
Call Conformance
~~~~~~~~~~~~~~~~

:dp:`fls_BBz4Iy7AeaU4`
:dt:`Call conformance` measures the compatibility between a set of :t:`[argument operand]s` and a set of :t:`[function parameter]s` or :t:`[field]s`.

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 copy fixes the old a set if typo, but the glossary copy at src/glossary.rst:683-685 still says a set if, so the two definitions now diverge. Since this PR is aligning glossary and main-text terminology, could we sync the glossary definition too?

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.


:dp:`fls_tsn6SUUG9LvW`
A :t:`method call expression` is equivalent to a :t:`call expression` where the
:t:`call operand` is the resolved :t:`method` and the adjusted
Expand Down
6 changes: 6 additions & 0 deletions src/general.rst
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,9 @@ relevant to the topic:
:dp:`fls_oxzjqxgejx9t`
The syntax representation of a :t:`construct`.

:dp:`fls_SonodAQVL5J4`
A :dt:`construct` is a piece of program text that is an instance of a :t:`syntactic category`.

.. rubric:: Legality Rules

:dp:`fls_gmx688d6ek1o`
Expand Down Expand Up @@ -253,6 +256,9 @@ together with context-dependent requirements expressed by narrative rules.
The semantic meaning of a Rust program is described by means of narrative rules defining
both the effects of each construct and the composition rules for constructs.

:dp:`fls_5SVthCNZBcVS`
A :dt:`syntactic category` is a nonterminal in the Backus-Naur Form grammar definition of the Rust programming language.

:dp:`fls_jsflt7691ye4`
The context-free syntax of Rust is described using a simple variant of the
Backus-Naur form. In particular:
Expand Down
8 changes: 5 additions & 3 deletions src/generics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,10 @@ A :t:`generic union` shall use all of its :t:`[type parameter]s` and
:t:`[lifetime parameter]s` at least once in at least one of its :t:`[field]s`.

:dp:`fls_hyi2jnp38v1n`
A :t:`generic parameter` is said to constrain an :t:`implementation` if the
:t:`generic parameter` appears at least once in one of the following:
A :t:`generic parameter` is said to :dt:`constrain` an :t:`implementation` if it makes the applicability of the :t:`implementation` more narrow.

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 old wording here, and the Rust Reference, made the bullet list the direct rule for when a generic parameter constrains an implementation. This rewrite replaces that with a broader gloss and moves the actual criterion into a separate sentence about when "a constraint happens", which makes the rule less explicit. Could we keep the direct formulation here, or otherwise say explicitly that a generic parameter constrains the implementation exactly when it appears in one of the following places? If so, src/glossary.rst:939 may need the same tightening, though that broader glossary phrasing predates this PR.

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.

hm, am thinking this is fine as the new rule is still accurate, and that it is fine for rules to be further tightened with other rules

am happy to change this though if you feel strongly... I feel weakly, but I did this to avoid definitions being defined by lists, instead of being able to stand alone

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.

"Constrain" is a very broad notion, so I do not think it should be made into a term. The former wording acts as an introduction to the various cases enumerated below.

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.

@kirtchev-adacore am in favor of that... probably kept since it was already made a term before this pr

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 paragraph should be expressed in terms of a "generic constraint". If you search the FLS, you will find two other very different instances of "to contain" / "constraint".

How about:

A generic constraint is a limitation imposed on an implementation by a generic parameter.

A generic parameter constrains (link to "generic constraint") an implementation if ...

It is a static error if a lifetime parameter ... without constraining (link to "generic constraint") the implementation.


:dp:`fls_cxNAtLSLjqbQ`
A :t:`[constrain]t` happens when a :t:`generic parameter` appears at least once in one of the following:

* :dp:`fls_sseo6u6pbcki`
As a :t:`binding argument` in the :t:`[trait bound]s` of a :t:`type` that
Expand Down Expand Up @@ -461,7 +463,7 @@ of the :t:`type parameter`.
Any remaining :t:`[generic parameter]s` without corresponding conformant
:t:`[generic argument]s` are :t:`[constant parameter]s` with
:t:`[constant parameter initializer]s`, :t:`[lifetime parameter]s` with
either inferred :t:`[lifetime argument]s` or :t:`[elided lifetime]s`,
either inferred :t:`[lifetime argument]s` or :t:`elided lifetimes <lifetime elision>`,
:t:`[type parameter]s` with :t:`[type parameter initializer]s` or inferred
:t:`[type argument]s`, and

Expand Down
Loading
Loading