Skip to content

Implement semantic analysis for named Fn trait params - #162634

Merged
rust-bors[bot] merged 10 commits into
rust-lang:mainfrom
JonathanBrouwer:named-fn-trait-params-semantics
Sep 14, 2026
Merged

rust-bors[bot] merged 10 commits into
rust-lang:mainfrom
JonathanBrouwer:named-fn-trait-params-semantics

Conversation

@JonathanBrouwer

@JonathanBrouwer JonathanBrouwer commented Sep 11, 2026

Copy link
Copy Markdown
Member

This PR can be reviewed commit by commit.
Every commit passes uitests individually.

The goal of this PR is to make the semantic of named fn trait parameters match those of fn pointers, which is what was decided on the RFC: rust-lang/rfcs#3955.
This is achieved, which can be observed by the fact that the output of the named-fn-trait-params.rs test matches that of fn-ptr-pattern.rs.

This PR also marks the feature as complete.

Tracking issue: #158499

@JonathanBrouwer JonathanBrouwer added the F-named_fn_trait_parameters `#![feature(named_fn_trait_parameters)]` label Sep 11, 2026
@rustbot

rustbot commented Sep 11, 2026

Copy link
Copy Markdown
Collaborator

The parser was modified, potentially altering the grammar of (stable) Rust
which would be a breaking change.

cc @fmease

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Sep 11, 2026
@rustbot

rustbot commented Sep 11, 2026

Copy link
Copy Markdown
Collaborator

r? @folkertdev

rustbot has assigned @folkertdev.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler
  • compiler expanded to 76 candidates
  • Random selection from 21 candidates

Comment on lines +106 to +107
/// A Parenthesized Argument List `impl Fn(...)`
ParenthesizedArgumentList,

@folkertdev folkertdev Sep 13, 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.

Any argument list is parenthesized though, right? idk, would FnTraitArgumentList work?

View changes since the review

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.

Apparently this is sort of an established name. Not the best name, but I'm OK with it with that context.

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.

Yeah this is the established name for this, indeed also not sure I like it...

Comment thread compiler/rustc_parse/src/parser/path.rs Outdated
req_body: false,
};
let param = p.parse_param_general(&mode, first_param, false)?;
let param = p.parse_param_general(&mode, first_param, true)?;

@folkertdev folkertdev Sep 13, 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 believe that all call sites of parse_param_general now pass true for recover_arg_parse. It's probably useful to keep around, but maybe can be hidden from the api until it is needed again?

Those random bool arguments don't spark joy.

View changes since the review

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.

Hmmm honestly I feel like that parameter is not very useful anymore, it can always be re-added in the future if this happens to be needed, it's a simple change that only affects diagnostics.
So I will remove it

}

fn visit_path_segment(&mut self, seg: &PathSegment) -> Self::Result {
if let Some(Parenthesized(args)) = &seg.args {

@folkertdev folkertdev Sep 13, 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.

Ah, I assume this is where the Parenthesized name came from? It is currently documented as

/// The `(A, B)` and `C` in `Foo(A, B) -> C`.

pre-existing but I'd really prefer

/// The `(A, B)` and `C` in `Fn(A, B) -> C`.

View changes since the review

@fmease fmease Sep 13, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The path that has the parenthesized generic arguments isn't forced to be of the form Fn* (as you probably know). This type is part of the AST so it makes sense for the docs to deliberately "generalize" the example to signal to the reader that it's immaterial what the path is.

Even semantically speaking, the path could be std::ops::Fn, FnMut, AsyncFn, core::ops::AsyncFnOnce, X (if the user did use Fn as X;), Y (if the user defined a trait with #[rustc_paren_sugar]), etc.

@fmease fmease Sep 13, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ah, I assume this is where the Parenthesized name came from?

It's a well-established convention across fields that ( ) are (round) parentheses or round brackets, [ ] are (square) brackets, { } are (curly) braces or curly brackets, < > are angle brackets. Of course, there are various deviations & competing conventions.

In any case, in rustc if you see parens that's ( ), brackets that's [ ]; braces that'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.

In the general case that naming makes sense, but the usage earlier appears to be more specific, and e.g. fn(...) could also be said to have a parenthesized argument list.

Also, just as a data point, I spent some time squinting at Foo(A, B) -> C and especially Foo(A, B) in the comment above, unsure about where that could occur. So specifically mentioning the function traits would have helped there.

@fmease fmease Sep 13, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Right, that's fair, I missed that nuance to your statement. In this case, it's parenthesized parameter list as contrasted with angle-bracketed parameter list. Of course, since the (unstable) introduction of RTN (e.g., T::f(..)) it's become more blurry.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

fn(...) could also be said to have a parenthesized argument list.

In the case of fn(…) … / fn …(…) … / |…| … the list is not an argument list but a parameter list actually, so no :P

Funnily, this unstable feature actually blurs the line between arguments ("actual parameters") & parameters ("formal parameters") because it (ab)uses the syntax of parameter lists for argument lists.

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.

Changed to something that should make you both happy

The `(A, B)` and `C` in `Foo(A, B) -> C`, used for the `Fn` trait among others.

@JonathanBrouwer

Copy link
Copy Markdown
Member Author

@rustbot ready

@JonathanBrouwer JonathanBrouwer changed the title Implement semantic analysis for named fn trait params Implement semantic analysis for named Fn trait params Sep 14, 2026
@folkertdev

Copy link
Copy Markdown
Contributor

@bors r+

@rust-bors

rust-bors Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

📌 Commit 99bb4bb has been approved by folkertdev

It is now in the queue for this repository.

@rust-bors rust-bors Bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 14, 2026
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Sep 14, 2026
…ams-semantics, r=folkertdev

Implement semantic analysis for named `Fn` trait params

This PR can be reviewed commit by commit.
Every commit passes uitests individually.

The goal of this PR is to make the semantic of named fn trait parameters match those of `fn` pointers, which is what was decided on the RFC: rust-lang/rfcs#3955.
This is achieved, which can be observed by the fact that the output of the `named-fn-trait-params.rs` test matches that of `fn-ptr-pattern.rs`.

This PR also marks the feature as complete.

Tracking issue: rust-lang#158499
rust-bors Bot pushed a commit that referenced this pull request Sep 14, 2026
…uwer

Rollup of 15 pull requests

Successful merges:

 - #162752 (`rust-analyzer` subtree update)
 - #161903 (Fix initialization cycle in `target_config`)
 - #162240 (Garbage-collect old incremental compilation sessions)
 - #162610 (fix tailcall indirect return)
 - #162634 (Implement semantic analysis for named `Fn` trait params)
 - #161675 (document that t-lang does not need involvement for unobservable intrisics)
 - #162160 (turn aligned-in-packed error into lint)
 - #162504 (Stabilize `unsafe_cell_access`)
 - #162516 (tidy: Sort multi-line types by treating `>` as a closing bracket)
 - #162630 (Simplify the `G` in `Diag<'a, G>`)
 - #162647 (Add regression test for previous overflow evaluating the requirement)
 - #162703 (regression test for valtree leaf const)
 - #162723 (Add regression test for unexpected type for constructor)
 - #162735 (Remove pointless `A: Allocator` bounds in boxed.rs)
 - #162736 (clean up trivial region constraint filtering)
rust-bors Bot pushed a commit that referenced this pull request Sep 14, 2026
…uwer

Rollup of 16 pull requests

Successful merges:

 - #162762 (Subtree sync for rustc_codegen_cranelift)
 - #162752 (`rust-analyzer` subtree update)
 - #161903 (Fix initialization cycle in `target_config`)
 - #162240 (Garbage-collect old incremental compilation sessions)
 - #162610 (fix tailcall indirect return)
 - #162634 (Implement semantic analysis for named `Fn` trait params)
 - #161675 (document that t-lang does not need involvement for unobservable intrisics)
 - #162160 (turn aligned-in-packed error into lint)
 - #162504 (Stabilize `unsafe_cell_access`)
 - #162516 (tidy: Sort multi-line types by treating `>` as a closing bracket)
 - #162630 (Simplify the `G` in `Diag<'a, G>`)
 - #162647 (Add regression test for previous overflow evaluating the requirement)
 - #162703 (regression test for valtree leaf const)
 - #162723 (Add regression test for unexpected type for constructor)
 - #162735 (Remove pointless `A: Allocator` bounds in boxed.rs)
 - #162736 (clean up trivial region constraint filtering)
@rust-bors
rust-bors Bot merged commit fa6e214 into rust-lang:main Sep 14, 2026
13 checks passed
@rustbot rustbot added this to the 1.100.0 milestone Sep 14, 2026
rust-bors Bot pushed a commit that referenced this pull request Sep 14, 2026
Rollup merge of #162634 - JonathanBrouwer:named-fn-trait-params-semantics, r=folkertdev

Implement semantic analysis for named `Fn` trait params

This PR can be reviewed commit by commit.
Every commit passes uitests individually.

The goal of this PR is to make the semantic of named fn trait parameters match those of `fn` pointers, which is what was decided on the RFC: rust-lang/rfcs#3955.
This is achieved, which can be observed by the fact that the output of the `named-fn-trait-params.rs` test matches that of `fn-ptr-pattern.rs`.

This PR also marks the feature as complete.

Tracking issue: #158499
@rust-timer

Copy link
Copy Markdown
Collaborator

Note

This PR was benchmarked as part of triage of its containing rollup: triage URL.

Finished benchmarking commit (0c6f4b2): comparison URL.

Overall result: ❌✅ regressions and improvements - no action needed

@rustbot label: -perf-regression

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
0.3% [0.3%, 0.3%] 1
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-0.2% [-0.2%, -0.2%] 1
All ❌✅ (primary) - - 0

Max RSS (memory usage)

This perf run didn't have relevant results for this metric.

Cycles

This perf run didn't have relevant results for this metric.

Binary size

This perf run didn't have relevant results for this metric.

Bootstrap: missing data
Artifact size: 406.96 MiB -> 406.93 MiB (-0.01%)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

F-named_fn_trait_parameters `#![feature(named_fn_trait_parameters)]` S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants