Repository navigation
Implement semantic analysis for named Fn trait params
#162634
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
19978b4
acc7dd9
19c0f5c
e603db4
f1e7b1e
26ba932
930507e
70339fc
d5e94f2
99bb4bb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -103,6 +103,8 @@ pub(crate) enum FnContext { | |
| Free, | ||
| /// A Function Pointer Type `fn(..)`. | ||
| FunctionPtrType, | ||
| /// A Parenthesized Argument List `impl Fn(...)` | ||
| ParenthesizedArgumentList, | ||
|
Comment on lines
+106
to
+107
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any argument list is parenthesized though, right? idk, would
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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... |
||
| /// A Trait context. | ||
| Trait, | ||
| /// An Impl block. | ||
|
|
@@ -691,7 +693,7 @@ impl<'a> Parser<'a> { | |
| let (mut params, _) = self.parse_paren_comma_seq(|p| { | ||
| p.recover_vcs_conflict_marker(); | ||
| let snapshot = p.create_snapshot_for_diagnostic(); | ||
| let param = p.parse_param_general(fn_parse_mode, first_param, true).or_else(|e| { | ||
| let param = p.parse_param_general(fn_parse_mode, first_param).or_else(|e| { | ||
| let guar = e.emit(); | ||
| // When parsing a param failed, we should check to make the span of the param | ||
| // not contain '(' before it. | ||
|
|
@@ -724,7 +726,6 @@ impl<'a> Parser<'a> { | |
| &mut self, | ||
| fn_parse_mode: &FnParseMode, | ||
| first_param: bool, | ||
| recover_arg_parse: bool, | ||
| ) -> PResult<'a, Param> { | ||
| let lo = self.token.span; | ||
| let attrs = self.parse_outer_attributes()?; | ||
|
|
@@ -812,13 +813,22 @@ impl<'a> Parser<'a> { | |
| // If this is a C-variadic argument and we hit an error, return the error. | ||
| Err(err) if this.token == token::DotDotDot => return Err(err), | ||
| Err(err) if this.unmatched_angle_bracket_count > 0 => return Err(err), | ||
| Err(err) if recover_arg_parse => { | ||
| Err(err) => { | ||
| // Recover from attempting to parse the argument as a type without pattern. | ||
| err.cancel(); | ||
| this.restore_snapshot(parser_snapshot_before_ty); | ||
| this.recover_arg_parse(fn_parse_mode.context)? | ||
| match this.recover_arg_parse(fn_parse_mode.context) { | ||
| Ok(res) => { | ||
| // We managed to parse the argument as a pattern, cancel the original error and emit a better one | ||
| err.cancel(); | ||
| res | ||
| } | ||
| Err(new_err) => { | ||
| // We did not manage to parse the argument as a pattern, avoid suggesting a pattern and emit the original error | ||
| new_err.cancel(); | ||
| return Err(err); | ||
| } | ||
| } | ||
| } | ||
| Err(err) => return Err(err), | ||
| } | ||
| }; | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
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
Parenthesizedname came from? It is currently documented aspre-existing but I'd really prefer
View changes since the review
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
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 diduse Fn as X;),Y(if the user defined a trait with#[rustc_paren_sugar]), etc.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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{}.There was a problem hiding this comment.
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) -> Cand especiallyFoo(A, B)in the comment above, unsure about where that could occur. So specifically mentioning the function traits would have helped there.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
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.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the case of
fn(…) …/fn …(…) …/|…| …the list is not an argument list but a parameter list actually, so no :PFunnily, 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.
There was a problem hiding this comment.
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