Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 25 additions & 2 deletions proposals/csharp-11.0/low-level-struct-improvements.md
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)]

Expand Down Expand Up @@ -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* and *ref-safe-context* of arguments to member initializer indexers that can escape to the receiver.
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)
Copy link
Member

Choose a reason for hiding this comment

The 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;

Copy link
Member Author

Choose a reason for hiding this comment

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

Doing it that way would mean that the safe-context of x is calling method because only heapSpan is used in the variable declaration. The motivation for putting all of the other values in the constructor is to solve issues like this.

```

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>

Expand Down