Stabilize attributes on closure and method call expressions#159581
Stabilize attributes on closure and method call expressions#159581Unique-Usman wants to merge 1 commit into
Conversation
|
Some changes occurred in tests/ui/sanitizer cc @rcvalle |
|
r? @folkertdev rustbot has assigned @folkertdev. Use Why was this reviewer chosen?The reviewer was selected based on:
|
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
We generally do reference updates separately. you can open a PR over there and link it to this one.
There was a problem hiding this comment.
Noted, thanks.
Allow outer attributes directly on closure and method-call expressions without requiring stmt_expr_attributes. This also covers parenthesized expressions and complete method-call chains. Keep the feature gate for other expression kinds, including function calls, field accesses, indexing, binary expressions, and literals.\n\nUpdate UI tests and the Rust Reference to reflect the newly stable positions, and remove now-unused stmt_expr_attributes declarations from closure and coroutine tests. Signed-off-by: Usman Akinyemi <usmanakinyemi202@gmail.com>
a5c7c08 to
e040823
Compare
|
The job Click to see the possible cause of the failure (guessed by this bot) |
|
Some of this already is stable, isn't it? This works on stable: fn foo(x: Option<i32>) {
x.map(#[inline] |y| y+1);
// does not work: let closure = (#[inline] || 42);
}OTOH with a So, looks like attributes on expressions are already partially stabilized, but this stabilizes them a bit more? |
You have to add curlies, it's also allowed for the trailing expression in a block: let _x = {
#[inline]
|| ()
};but tool attributes are not allowed there on stable let _x = {
#[rustfmt::skip]
|| ()
}; |
This form is already stabilized, this is a summary of what has already being stabilized before this pr #15701 (comment)
Exactly, it stabilized unambiguous expression forms. |
|
This will need to be audited by me for historical context and macros, and by @fmease for the current parser state. Using something being a closure or a method call as a criterion seems to be a distraction, if something like #[attr]
method.call() + rhs;starts working after this PR, it means the core ambiguity preventing the stabilization is not resolved. |
This is already being stabilized before this pr.
Thanks for the comment, definitely, auditing the pr will really be appreciated. I have actually done a sort of deep study and understanding of what has already being stabilzed and what was not stabilized and for what reason they were not stabilized and also added the relevant links or discussions which confirms what was stabilized or what was not and I wrote a detailed summary for that here: #15701 (comment) and also suggested a pathway forward and which lead to me working on this pr and the fact that some people show interest in it. I will add the link of the summary to the stabilization report. Thanks once again. |
Where? I don't think this should be stabilized, |
oops, confirming it again, I was using the rust compiled version of this pr. @petrochenkov, thanks for pointing this out. This pr should not stabilized attribute of this particular expression. |
Stabilization report
Summary
This PR partially stabilizes outer attributes on expressions under the existing
stmt_expr_attributesfeature.It stabilizes attributes directly on closure expressions and method-call
expressions, including parenthesized forms and complete method-call chains:
RFC 16 proposed broader support for attributes on statements and expressions.
Several unambiguous positions have already become stable, including statements,
blocks, match arms, and elements of arrays, tuples, and function argument lists.
General expression attributes remain unstable because it may be unclear which
expression an initial attribute applies to.
This stabilization selects closures and method calls, whose attribute targets
are clear, while leaving the remaining expression and subexpression cases
behind
stmt_expr_attributes.Tracking and related work:
stmt_expr_attributestracking issue #15701Two I opened together with this one for reference update and the for rejecting cfg one expressions that cannot be safely remove:
cfgon expressions that cannot be safely removed #159580cc @rust-lang/lang @rust-lang/lang-advisors @rust-lang/lang-docs @rust-lang/compiler
What is stabilized
Closure expressions
Outer attributes may be placed directly on closures without enabling
stmt_expr_attributes:This stabilizes the attribute position. Existing target validation still
determines whether a particular attribute may be applied to a closure.
Method-call expressions
Outer attributes may be placed directly on method-call expressions:
For a method-call chain, the attribute applies to the complete resulting
method-call expression:
Parentheses around a closure or method call do not change whether the position
is stable:
What is not stabilized
The
stmt_expr_attributesfeature itself remains unstable. Attributes on otherexpression kinds continue to require the feature gate.
For example, these remain unstable:
Although
object.method().fieldcontains a method call, its outer expression isa field expression, so it is outside this stabilization.
This PR does not decide the behavior of attributes on arbitrary literals,
function calls, field expressions, indexing, binary expressions, or other
remaining expression and subexpression positions.
There is also a detailed summary report I created after deeply studying what was stabilized, what has not been stabilized and where were they confirmed to be stabilized and the summary can be find here: - #15701 (comment)
Design
The primary concern with general expression attributes is identifying the
expression to which an initial attribute belongs. For example:
#[attr] a + bcan raise readability and precedence questions about whether the attribute
belongs to
aor to the complete binary expression.Closures have a distinct syntactic introducer:
#[attr] || expressionMethod calls form a clear postfix expression:
For chained calls, the complete chain is represented by an outer method-call
expression. The attribute consequently applies to the complete chain.
This partial stabilization does not introduce additional feature gates. The
existing
stmt_expr_attributesgate remains active for all expression kindsoutside the stated boundary.
Interaction with
cfgStabilizing an attribute position does not mean that
#[cfg]may remove anexpression required by its parent.
For example:
cannot be configured away because that would leave the initializer incomplete.
It continues to produce:
rust-lang/rust#159580
ensures that
cfgon expressions that cannot be safely removed is rejectedregardless of whether the configuration evaluates to true or false.
Positions where
cfgcan safely remove a complete element, such as an array,tuple, or function argument element, are unaffected.
Implementation
The parser and AST already support this syntax, so this stabilization does not
change the grammar or AST representation.
The expression-attribute feature-gate checker now receives the attributed
ast::Expr. Before emitting thestmt_expr_attributesdiagnostic, itrecognizes:
ExprKind::ClosureExprKind::MethodCallExprKind::Parencontaining either of those expressionsThe expression node is passed through the relevant ordinary expansion,
optional-expression expansion, and
cfg_evalconfiguration paths so that theyall apply the same stability rule.
The
stmt_expr_attributesentry remains incompiler/rustc_feature/src/unstable.rs; it is not moved toaccepted.rs.Test coverage
Positive tests cover:
cfg_eval.#[inline],#[cold],#[coroutine], capture-analysis, and#[track_caller]uses on closures.Negative tests verify that the following remain gated:
Configuration tests verify that a required method-call expression cannot be
removed with
#[cfg(false)].Existing closure-analysis tests were updated only to remove their obsolete E0658
expectations. Their intended capture-analysis diagnostics remain. Coroutine
tests no longer enable
stmt_expr_attributessolely to place#[coroutine]ona closure.
Compatibility and language interactions
This is an additive change. Programs previously accepted on stable Rust remain
accepted, so a crater run is not expected to be necessary.
This stabilization:
cfg_eval, coroutines, or individual unstable attributes.stmt_expr_attributesfor all other expression kinds.Tools and documentation
No Cargo, rustdoc, Clippy, rustup, or docs.rs changes are required because no new
syntax or AST form is introduced. The syntax was already available on nightly.
Rustfmt and rust-analyzer use the existing expression-attribute syntax, but
their behavior should be confirmed during review.
Reference PR #2314:
method-call expression.
inline,cold, andinstruction_setdocumentation so that itno longer describes direct closure expression attributes as unsupported.
The Reference PR must be reviewed and approved by the lang-docs team before this
stabilization is merged.
Outstanding concerns
No known implementation or soundness issue specifically blocks this narrow
stabilization.
The broader design questions tracked in
#15701 and
#127436 remain relevant to
the expression kinds that are not being stabilized.
An existing FIXME notes differences between ordinary and optional expression
feature-gating paths. Both paths are updated and tested by this implementation,
so it does not block this stabilization.
Contributors and prior work
The current work builds on contributions from:
original RFC;
[rust-lang/rust#29850](Implements RFC 16, attributes on statements and expressions. #29850);
[rust-lang/rust#36995](stabilise ?, attributes on stmts, deprecate Reflect #36995);
the remaining feature into narrower stabilization candidates;
#[cfg]safetyfix, tests, and Reference update.
Acknowledgments
Thanks to the authors and implementers of RFC 16 and to everyone involved in
the expression-attribute discussions, implementations, and previous
stabilizations, including the contributors to #15701, #32796, #36995, #127436,
#134661, #159580, and the corresponding Reference work. Thanks to my rust compiler mentor @estebank and thanks to @WaffleLapkin for helping.