# C# Language Design Meeting for November 30th, 2022

## Agenda

- [Revise `MemberNotNull` for `required`](#revise-membernotnull-for-required)
- [`params Span<T>`](#params-spant)

## Quote of the Day

- "I understand I'm broken."

## Discussion

### Revise `MemberNotNull` for `required`

https://github.com/dotnet/csharplang/issues/6754  
https://github.com/dotnet/csharplang/issues/3630

Today we considered a revision to `required` members, part of the recently-shipped C# 11, before the current behavior gets too broadly used for us to
make changes without a language version bump. Specifically, we looked at whether we can use `MemberNotNullAttribute`s on member declarations to inform
nullability error suppression for fields initialized by required properties. While we do think this will become less of an issue with future language
versions that take up the `field` feature, we think this is a good workaround for the moment. It uses `MemberNotNullAttribute` as a linking mechanism,
which was the intended purpose of the attribute, and we're in favor of making the change now while we still can.

#### Conclusion

Proposed change is accepted, targeted at 7.0.200.

### `params Span<T>`

https://github.com/dotnet/csharplang/issues/1757  
https://github.com/dotnet/csharplang/blob/6ab4bbf1ec5183c65ad63887b8ec9e73ca0aab67/proposals/params-span.md

The params improvements working group has come back from their initial investigations with some initial work. Of the potential work, they looked at
`params ReadOnlySpan<T>` as the most interesting thing on the plate, as it makes for real performance improvements, while other ergonomic benefits
will potentially be addressed by collection literals. The performance benefits here are mainly targeted at new APIs, as existing APIs (such as
`Console.WriteLine`) have already manually optimized these cases by introducing a number of overloads, each taking another argument, until finally
leaving a last `params` API. While these APIs would likely still take advantage of them (the runtime is tracking what APIs will want to use the
feature in [this issue](https://github.com/dotnet/runtime/issues/77873)), the main improvement will be in new APIs that don't need to write so many
overloads in the first place. Some questions we raised during discussion:

* Why do we want to support `UnscopedAttribute` on `params`? We don't think this is a real scenario, and it adds significant complexity to the rules.
* We need to make sure that our adjustments to Better Function Member aren't introducing any new ambiguities. We don't think they are at first look,
  but this area often has hidden breaks so we need to make sure.
* We spent a lot of time talking about the proposed strategy of always allocating on the stack. There was particular concern with how this interacts
  with another major part of the feature: introducing `params ReadOnlySpan<T>` parameters and recompiling will prefer the span overload. For callsites
  with large numbers of params parameters this could end up causing `StackOverflowExceptions`. There are a few possible mitigations:
    * The runtime can introduce a side-stack for these allocations, so params backing storage is still on a stack, just a different stack.
    * We could (and probably should) make the wording here much looser, allowing the compiler more latitude in choosing what to do here.
    * This would then allow the compiler to call a runtime helper to make the decision, as different platforms have different stack sizes and that
      would influence what they would want to be allocated where.
    * Should users be able to turn off the feature at the compilation-level such that backing arrays are always heap allocated? This would give a good
      way for users to test to see if the feature is causing issues for them.
    * Ultimately we decided that we should lean on the runtime to make allocation location decisions, and we can look at a global switch if we end up
      seeing problems in preview/release.

#### Conclusion

Feature is good to proceed to implementation.
