NEW GOALS
* User-wide caching (orphaned, cargo team)
REMOVED GOALS
* Experiment with relaxing the Orphan Rule dropped
for bandwidth concerns. (We may reframe.)
SIMPLIFIED GOALS
* Patterns of empty types -> moral support
In the lang design meeting on 2024-06-26, we adopted a slate of five
rules for match ergonomics. We later amended *Rule 4* in our meeting
on 2024-07-03.
These five rules, as amended, form the normative description of what
the lang team means for the rules to be. Therefore, in the
reference-level explanation, let's include these rules verbatim and
note that the remaining sections describe these rules further.
We've been using "tracking issue" rather than "rust issue" recently,
so let's adjust that. Let's also use sentence case for the title and
remove some remaining bits left over from the RFC template. And let's
replace some Unicode characters that don't have ubiquitous font
support with ASCII equivalents.
We specify that the details about the traits, including the associated
types, are implementation details. Let's make the section describing
this, with respect to the associated types, more clear and give an
example.
(Thanks to RalfJ and Yosh for raising that this section could be
clarified.)
Since we're leaving as open the question of whether to say `impl
use<..> Trait` or `use<..> impl Trait`, we had earlier weakened some
language that was previously decisive. We missed one spot, though, so
let's make this sentence less decisive as well.
We had a sentence that would be correct if we had not already
stabilized RPIT in trait impls. Since we have, let's more precisely
describe where lifetime parameters are not implicitly captured.
We had in this RFC chosen `impl use<..> Trait`. But there's been
meaningful discussion about whether this should instead be `use<..>
impl Trait`, so let's mark this question as unresolved.
The FCP for RFC 3484 completed on 2024-05-04 with a disposition to
merge. The lang team further confirmed its happiness with the RFC in
a meeting on 2024-05-08. Let's merge the RFC.
Without this adjustment, it would not be possible to use this macro with
types such as the `ARef` type that was discussed on the RFC thread [1],
since we need `AlwaysRefcounted` to be specified for both T and U.
Link: https://www.github.com/rust-lang/rfcs/pull/3621#issuecomment-2094094231 [1]
The 2023-10-11 consensus from lang on how to move forward included
that the `safe` and `unsafe` keywords would be optional within an
`unsafe extern` block.
The reference-level section correctly followed this consensus, but the
guide-level section did not, and suggested that annotating items with
these keywords was required. Let's fix that.
This RFC had used as one motivation that undefined behavior can
currently result simply from having an incorrect `extern` block even
if the items within are not used from Rust code.
This motivation was not cited in the lang team's 2023-10-11 consensus
for how and why to proceed with this RFC, and it's possible that we
may be able to resolve this issue in other ways, so let's remove that
motivation from this RFC.
(Thanks to RalfJ for raising this point and suggesting this.)
When people migrate to the new edition, if they have turned up the
severity of the `unsafe_code` lint and they have `extern` blocks that
need to be marked `unsafe`, they will see this lint as intended.
Let's make a note of that.
(Thanks to kennytm for raising this point.)
Even if the C standard allows for what LLVM is doing, we could still
conceivably fix LLVM. In the text, let's draw this out a bit more
finely.
(Thanks to RalfJ for raising this point.)
One possibility we should mention is that of changing the behavior of
LLVM and then not adding `unsafe extern`, so let's mention that.
(Thanks to RalfJ for raising this point.)
As this RFC was reviewed in the GitHub thread, many alternatives were
proposed and questions raised. As those of us who were a bit too
close to it were cursed with knowledge, the rationale for rejecting
these alternatives were not fully articulated and not all of these
questions were clearly answered.
Let's better document these alternatives, the rationale for rejecting
each, and the answers to various known questions.
(Thanks to GoldsteinE, madsmtm, kennytm, samih, and tmccombs for
raising these alternatives and questions.)
This RFC means to specify that we will *eventually* issue a lint in
all editions when `extern` is not prefixed with `unsafe`. Let's
specify this more clearly.
(Thanks to Waffle and joshtriplett for raising this point.)
There's a long history of discussion on how incorrect declarations in
`extern` blocks might cause UB in programs compiled using LLVM. Let's
link to one of the issues in that history.
(Thanks to madsmtm for raising this question, and to RalfJ for
providing this citation.)
An incorrect declaration in an `extern` block may cause undefined
behavior in the resulting program. Let's clarify that in the text.
(Thanks to Waffle for raising this point.)
During the FCP, people noticed that the wording of the drawback
probably fit better with an earlier draft of this RFC. Let's
incorporate that feedback before merging.
(Thanks to Waffle for raising this point.)
The FCP for RFC 3593 has completed, so let's prepare it to be merged.
In this case, that means changing the file name to use dashes rather
than underscores as separators and updating the tracking issue.
The FCP has completed on RFC 3606, so let's prepare it to be merged.
First, we'll shorten the name of the feature flag a bit; this should
still be unambiguous.
Second, we're going to remove the graphic from the summary. While it
may be illustrative, the text and the other examples seem clear enough
without it, and its benefits have to be weighed against the fact that
we want the content in this repository to be easily editable and
freestanding. Pulling in an SVG file from an outside host pulls
against that. If we come to think the graphic is critical, we could
always add it back in a separate PR that would add an editable version
of this SVG file into the repository itself.
Third, let's make the H1 title of the document a bit more clear.
The FCP for RFC 3519 ("Arbitrary self types v2") is complete. Let's
reuse the existing `arbitrary_self_types` feature flag for this work,
and similarly, let's reuse the existing tracking issue.
During the FCP, some questions came up related to how refinement and
reparameterization in the impl are handled. This handling is implied
by other text in the RFC and by the existing behavior of Rust, so
let's go ahead and add clarifications to address these questions.
The hardest of these questions relate to how things would behave if we
were to allow `use<..>` in trait definitions to not capture the
generic input parameters to the trait (including `Self`). It's
unlikely this will be possible for the foreseeable future, and while
we will not leave these as open questions, certainly much might be
learned between now and the point at which that might become possible,
so we'll make note of that.
We'll also add a clarification to address a question that came up in
the 2024-04-24 design meeting about what it means to capture a const
generic parameter.
(Thanks to aliemjay for raising many of these great questions.)
We had added an RPITIT desugaring that was rather complicated. This
complication was due to trying to explain what it would mean to not
capture generic parameters that are part of the trait header.
However, it's likely that there's no good way to express that semantic
in the surface syntax. Let's instead simplify the desugaring and make
a note of its limitations.
We had included a reference desugaring of `use<..>` in RPIT using
ATPIT. Let's add a similar desugaring for `use<..>` in RPITIT.
In doing this, we'll make some changes to the RPIT desugaring so that
it better parallels the RPITIT one. In particular, we want to
turbofish all generic parameters for clarity, and we want to eliminate
all function arguments for conciseness. Doing this means that all of
the lifetimes become early bound. This seems fine, since it's rather
orthogonal to the semantics we're trying to demonstrate here.
We also want to demonstrate using const generics in the hidden type.
We could do this using arrays, e.g. `[(); N]`, but it seems more clear
to just define a type constructor that uses all of the generics, so
we'll sacrifice a bit of conciseness to do it that way.
We have an example showing how to avoid capturing a higher ranked
lifetime in a nested opaque type so that the code can be migrated to
Rust 2024. However, because we didn't parameterize the trait in the
example with a lifetime, the code could be migrated by just removing
the `for<..>` binder. This makes the example weaker than it could be,
so let's strengthen it by parameterizing the trait.
(Thanks to aliemjay for raising this point.)
We had earlier written up a section on `use<..> impl Trait` syntax
that mostly focused on why we had not adopted it. We didn't spend
much text on why it's appealing, probably because we are in fact
sympathetic to it and consider the reasons that it's appealing
obvious.
Still, we should write all those reasons down. Let's extend the
section on this syntax with the best possible argument in favor.
We also see more clearly now the fundamental intuitive tension behind
this syntax and `impl use<..> Trait`, so let's write that down too.
Finally, let's describe the historical and other factors that led to
picking one syntax over the other.
(Thanks to tmandry for suggesting the `use<..> impl Trait` syntax and
many of the arguments in favor of it.)
As with other lists of generic arguments in Rust, the grammar for
`use<..>` specifiers supports an optional trailing comma. This is
already specified in the formal grammar, but let's also note this in
the guide-level section.
(Thanks to Josh Triplett for raising this point.)
In the T-lang design meeting on 2024-04-24, a new syntax option was
raised: `use<..> impl Trait`.
While some people liked this, others did not, and no clear consensus
formed to change the main proposal in this RFC. Nevertheless, let's
discuss this as an alternative.
For the formal syntax, we had used the existing `GenericParams`
production. However, that production isn't exactly appropriate for
this case. What's needed here is essentially a generic argument list
that only accepts generic parameters as elements.
Since none of the other existing productions provide this, we'll
define our own.
(Thanks to @kennytm for pointing this out.)
We had included one `use<T>` in a pre-migration example when it should
have only appeared in a post-migration example. Let's fix this error.
(Thanks to @kennytm for pointing this out.)
One way to think about `use<..>` is that, in Rust `use` brings things
into scope, and here we are bringing certain generic parameters into
scope for the hidden type. Let's point this out.
To fully stabilize, in Rust 2024, the Lifetime Capture Rules 2024 that
we accepted in RFC 3498, we need to stabilize some means of precise
capturing. This RFC provides that means.
We discussed this feature, the need for it, and the syntax for it in
the T-lang planning meeting on 2024-04-03. The document here follows
from that discussion.