-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Object initializer updates #8253
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 1 commit
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 |
|---|---|---|
| @@ -1,5 +1,4 @@ | ||
| Low Level Struct Improvements | ||
| ==== | ||
| # Low Level Struct Improvements | ||
|
|
||
| [!INCLUDE[Specletdisclaimer](../speclet-disclaimer.md)] | ||
|
|
||
|
|
@@ -411,6 +410,30 @@ Span<int> ComplexScopedRefExample(scoped ref Span<int> span) | |
| } | ||
| ``` | ||
|
|
||
| #### Rules for object initializers | ||
|
|
||
| The *safe-context* of an object initializer expression is narrowest of: | ||
|
|
||
| 1. The *safe-context* of the constructor call. | ||
| 2. The *safe-context* arguments to member initializer indexers that can escape to the receiver (can escape to *caller-context*) | ||
| 3. The *safe-context* of the RHS of assignments in member initializers to non-readonly setters or *ref-safe-context* in case of ref assignment. | ||
|
|
||
| Another way of modeling this is to think of any argument to a member initializer that can be assigned to the receiver as being an argument to the constructor. This is because the member initializer is effectively a constructor call. | ||
|
|
||
| ```c# | ||
| Span<int> heapSpan = default; | ||
| Span<int> stackSpan = stackalloc int[42]; | ||
| var x = new S(ref heapSpan) | ||
| { | ||
| Field = stackSpan; | ||
| } | ||
|
|
||
| // Can be modeled as | ||
| var x = new S(ref heapSpan, stackSpan) | ||
|
Member
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. Cannot it be modeled simply as this? var x = new S(ref heapSpan);
x.Field = stackSpan;
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. Doing it that way would mean that the safe-context of |
||
| ``` | ||
|
|
||
| This modeling is important because it demonstrates that our [MAMM][rules-method-arguments-must-match] need to account specially for member initializers. Consider that this particular case needs to be illegal as it allows for a value with a narrower *safe-context* to be assigned to a higher one. | ||
|
||
|
|
||
| ### Method arguments must match | ||
| <a name="rules-method-arguments-must-match"></a> | ||
|
|
||
|
|
||
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.
Should this be ref-safe-context of
refarguments to indexers (specifically, aninargument)?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 is a case of practically speaking no. The
inpart of an indexer can't escape intothisbecause it's return only. Hmm ... guess you could if it was[UnscopedRef]. Not sure if we have good testing for that. The 99% case is the value is what matters.Spec wise can say both thogugh.