-
Notifications
You must be signed in to change notification settings - Fork 86
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 for ref-valued methods, properties, et al. #837
Conversation
… locally at the moment :( )
Typos found in the first stage have been fixed. Comments on the first stage also addressed some longer standing issues, these have been addressed which means a few more files have been impacted. In particular double-spaces have been removed and some files have bene impacted just for that. There has been knowen issues with the sharing the clauses related to accessors, currently sub-clauses of Properties, between properties and indexer. Some duplication has been removed as part of this, and some *Note*s added. A re-org of some of this material could be warranted but this PR does not (currently) do that. Please review and fire submit your brickbats, and even bouquets, so we can get this sorted before Thursday if possible!
…ethods. The existing grammar for *method_declaration* *et al.* tended towards the less restrictive with the prose detailing the myriad of restrictions/combinations allowe/etc. It was quite gnarly at times and adding in returns-by-ref methods, and their set of restrictions, doesn’t help… The new grammar is a little more precise, though still liberal, which allows some of the prose to be removed (e.g. no need to say something is disallowed when its a grammartical impossibility) while adding in prose for the returns-by-ref case. I.e. I took some of the gnarly stuff out and replaced it new gnarly stuff, I make no claim it is over *less* gnarly just less than it would be wthout the grammar refactor… Of course the balance between grammar & prose semantic restrictions is subjective rather than objective, feel free to discuss. Still to do are local & anonymous functions, interfaces, a review of the delegate stuff, maybe something in the overrides… As before, please review and fire off your brickbats & bouquets and spot those sneaky typos!
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.
A few comments, but otherwise looks fine to me - which isn't to say I've verified it's complete; only that the changes here do make sense to me!
Comment for last commit – somehow I managed to kill This is the last set of changes to address #825 & #826 and covers local functions, delegate and interfaces. The grammar phrase The grammars for local functions, delegates & interfaces have also been updated to follow those for methods et al. to keep things consistent. Quite a few typos were found during the editing and these have been fixed, but don’t panic a similar number have probably been added so typo hunting is still required! ;-) Please fire off brickbats & bouquets as usual, but further changes prior to the next meeting are unlikely. Now everything is in theory done the “draft” status of this PR will be removed. |
@Nigel-Ecma: Can you take another pass at the comments on this PR now? I'm happy for merge as-is with future work noted in another issue, if that simplifies things. |
@jskeet – Will do, hopefully later this week…
… On 8/08/2023, at 3:29 am, Jon Skeet ***@***.***> wrote:
@Nigel-Ecma <https://github.com/Nigel-Ecma>: Can you take another pass at the comments on this PR now? I'm happy for merge as-is with future work noted in another issue, if that simplifies things.
—
Reply to this email directly, view it on GitHub <#837 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/ABSYVW63DVWZU3SXDXHKZYLXUECXPANCNFSM6AAAAAAZ72CFBU>.
You are receiving this because you were mentioned.
|
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.
Just a very few comments now - sorry not to be able to merge immediately, but I think you'll agree they should be fixed first.
…nock-on effect that a clause list constructed from those with notes was also wrong. Thanks to Jon for spotting this! Also a few typos fixed and minor wording changes.
@@ -356,7 +356,7 @@ The value of a local variable is obtained in an expression using a *simple_name* | |||
|
|||
The scope of a local variable declared in a *local_variable_declaration* is the block in which the declaration occurs. It is an error to refer to a local variable in a textual position that precedes the *local_variable_declarator* of the local variable. Within the scope of a local variable, it is a compile-time error to declare another local variable or constant with the same name. | |||
|
|||
A local variable declaration that declares multiple variables is equivalent to multiple declarations of single variables with the same type and `ref`/`ref readonly` prefix. Furthermore, a variable initializer in a local variable declaration corresponds exactly to an assignment statement that is inserted immediately after the declaration. | |||
A local variable declaration that declares multiple variables is equivalent to multiple declarations of single variables with the same type and *ref_kind*. Furthermore, a variable initializer in a local variable declaration corresponds exactly to an assignment statement that is inserted immediately after the declaration. |
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 no longer corresponds exactly, because of ref safety.
using System;
public class C {
public void M() {
Span<int> s1 = stackalloc int[1]; // OK
Span<int> s2;
s2 = stackalloc int[1]; // error CS8353
}
}
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.
I've filed #899 for this.
The raised error is:
CS8353: A result of a stackalloc expression of type 'Span<int>' cannot be used in this context because it may be exposed outside of the containing method
What logic is the compiler using to determine s2 may be exposed but not s1? Am I missing the glaringly obvious, its been a long day, or is something amiss here?
… On 17/08/2023, at 3:44 pm, KalleOlaviNiemitalo ***@***.***> wrote:
public void M() {
Span<int> s1 = stackalloc int[1]; // OK
Span<int> s2;
s2 = stackalloc int[1]; // error CS8353
}
|
Once a Span local has been initialised with stackalloc, it is apparently OK to assign other stackalloc expressions to it: using System;
public class C {
public void M() {
Span<int> s1 = stackalloc int[1]; // OK
s1 = stackalloc int[1]; // OK
}
} I get the impression that the ref safety aspects of the local variable depend on whether and how it is initialised, and they then affect whether further assignments are considered safe. But I haven't checked whether this is already specified adequately. |
9.7.2.1 (Local variable ref safe context):
So this is how the ref-safe-context depends on the initialiser. However the term "reference variable" defined in 9.7.1 does not cover |
Likewise in 9.7.2.8 (Limitations on reference variables) there's:
which does not cover assignment of |
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.
This looks good to me; I've filed a new issue for the latest problem noted by @KalleOlaviNiemitalo, but that wasn't introduced in this PR, so I'll merge this in the interests of making progress.
@@ -356,7 +356,7 @@ The value of a local variable is obtained in an expression using a *simple_name* | |||
|
|||
The scope of a local variable declared in a *local_variable_declaration* is the block in which the declaration occurs. It is an error to refer to a local variable in a textual position that precedes the *local_variable_declarator* of the local variable. Within the scope of a local variable, it is a compile-time error to declare another local variable or constant with the same name. | |||
|
|||
A local variable declaration that declares multiple variables is equivalent to multiple declarations of single variables with the same type and `ref`/`ref readonly` prefix. Furthermore, a variable initializer in a local variable declaration corresponds exactly to an assignment statement that is inserted immediately after the declaration. | |||
A local variable declaration that declares multiple variables is equivalent to multiple declarations of single variables with the same type and *ref_kind*. Furthermore, a variable initializer in a local variable declaration corresponds exactly to an assignment statement that is inserted immediately after the declaration. |
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.
I've filed #899 for this.
Ah... can't merge immediately due to conflicts. @Nigel-Ecma are you happy to rebase, or would you like me to do so? |
@jskeet – I’ll take a look my tomorrow and if you haven’t done it in your today I’ll see if I can do it without my usual git-breaking skill…
… On 17/08/2023, at 6:03 pm, Jon Skeet ***@***.***> wrote:
Ah... can't merge immediately due to conflicts. @Nigel-Ecma <https://github.com/Nigel-Ecma> are you happy to rebase, or would you like me to do so?
—
Reply to this email directly, view it on GitHub <#837 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/ABSYVW5N4PTLJPCBRQM2I73XVWX4RANCNFSM6AAAAAAZ72CFBU>.
You are receiving this because you were mentioned.
|
OK, the rule for how the initializer of a
That explains the CS8353 error. It is not necessary to change §9.7.2 to cover It could be useful to add a note to §9.7.2.1 (Ref safe contexts / General):
§16.4.12.1 (Safe context constraint / General) already has a link to §9.7.2:
Filed this as #901. |
I've managed to fix everything, but I can't force push to your branch. I'll force push to my fork, create a PR from that and merge it. |
(This was originally in dotnet#837.) The grammar has been extended to be as prescriptive as reasonably possible as befits a language specification[1], this means that former statements such as it being illegal to have a set accessor for a ref-valued property are now covered by the grammar. However the usual verbose description of the grammar remains! The term ref-valued rather than ref-returning is used, a term closer to the language of fields. To distingush the two kinds of properties, which do follow different rules, the corresponding and somewhat ugly term non-ref-valued is used (non-ref-returning would be just as ugly). [1] The grammar used by a compiler may be less restrictive to support more descriptive error messages, that is of course an implementation issue! Fixes dotnet#825.
(This was originally in #837.) The grammar has been extended to be as prescriptive as reasonably possible as befits a language specification[1], this means that former statements such as it being illegal to have a set accessor for a ref-valued property are now covered by the grammar. However the usual verbose description of the grammar remains! The term ref-valued rather than ref-returning is used, a term closer to the language of fields. To distingush the two kinds of properties, which do follow different rules, the corresponding and somewhat ugly term non-ref-valued is used (non-ref-returning would be just as ugly). [1] The grammar used by a compiler may be less restrictive to support more descriptive error messages, that is of course an implementation issue! Fixes #825.
Rebased as PR #900, so can close this one. |
This is a first draft of changes to address #825.
At this stage only ref-valued properties have been considered, other ref returning functions will follow later.
The grammar has been extended to be as prescriptive as reasonably possible as befits a language specification[1], this means that former statements such as it being illegal to have a
set
accessor for a ref-valued property are now covered by the grammar. However the usual verbose description of the grammar remains!The term ref-valued rather than ref-returning is used, a term closer to the language of fields. To distingush the two kinds of properties, which do follow different rules, the corresponding and somewhat ugly term non-ref-valued is used (non-ref-returning would be just as ugly).
Please fire off brickbats, and maybe even bouquets, on the direction of this. TIA
[1] The grammar used by a compiler may be less restrictive to support more descriptive error messages, that is of course an implementation issue!