csharplang/meetings/2020/LDM-2020-07-20.md
2020-07-20 15:52:41 -07:00

6.4 KiB

C# Language Design Meeting for July 20th, 2020

Agenda

  1. Finishing Triage a. Extend with expression to anonymous type b. Required properties c. Shebang support
  2. Private reference fields in structs with SkipLocalsInit

Quote of the Day

"If you go get a beer from the fridge or wherever you keep them and drink it right now, I'll refund you."

Discussion

Finishing Triage

Extend with expression to anonymous type

https://github.com/dotnet/csharplang/issues/3530

We don't see any reason why we couldn't extend with expressions to handle anonymous types, and we universally support the idea. We do see room for further improvement as well. Struct types should be generally possible to with, and in particular tuples should feel first class here. Some other ideas for future improvements that we'll need to keep in mind when designing anonymous types is an ability to specify a withable constraint: perhaps that's a thing we could do via typeclasses, but if that's a thing that should be specifiable then we'll want to make sure that whatever we do for structs and anonymous types works well with it.

Conclusion

Triaged into C# 10 for discussion with the other with enhancements

Required properties

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

A smaller group is currently fleshing this proposal out in the direction of initializer debt, and is looking to talk more about it in the next few months.

Conclusion

Triaged for C# 10.

Shebang support

https://github.com/dotnet/csharplang/issues/3507

This is part of the next step in the C# scripting discussion. In particular, this proposal details just one, very small piece of the puzzle here, namely the ability have a C# file startup an environment. There is significantly more work to be done in the language and tooling to effectively modernize the loose-files support for C#. Today, C# code has a core concept that cs files themselves do not contain information about the runtime environment. They don't specify the target runtime, nuget dependencies, where tools can be found, or anything else similar (beyond some #ifdef blocks). Supporting this would be intentionally eroding this aspect, which we need to make sure we're doing with intention and design. There is support among LDT members for this scenario, so we'll continue to look at.

Conclusion

Triaged into C# 10 for discussion. We acknowledge that we may well not ship anything in this space as part of C# 10, but we want to start discussing possible futures here in the coming X months, not X years.

Private fields in structs with SkipLocalsInit

https://github.com/dotnet/csharplang/issues/3431

Proposal 1: https://github.com/dotnet/roslyn/issues/30194#issuecomment-657858716 Proposal 2: https://github.com/dotnet/roslyn/issues/30194#issuecomment-657900257

This topic was brought up last week when we realized there was a potential hole in SkipLocalsInit with definite assignment, where we realized it's possible to observe uninitialized memory via private fields. When importing metadata, the native compiler ignored private fields, including private fields in structs, and did not require them to be considered definitely assigned before usage. This behavior was preserved when we implemented Roslyn, as attempting to break it was too large of a change for organizations to adopt. Both of these proposals ensure that, with SkipLocalsInit on a method, it's considered an error to not definitely assign here, which was fine with LDM as this is a new feature and cannot break anyone. We then looked at the differences between the two proposals, namely whether the definite assignment diagnostic should be a warning or an error when users opt into to a new warning wave. We found the arguments around incremental adoption compelling: we don't want users to be blocked off from adopting new warning waves and making their code at least a little safer by issuing errors that cannot be ignored. If users want to ensure that these warnings are fixed in their code, they can use warnAsError to turn these specific warnings or all warnings into errors, as you can today.

Conclusion

Proposal 1 has been chosen:

  1. If a method has the [SkipLocalsInit] attribute, or the compilation has the "strict" feature enabled, we use the strong version of analysis for its body. Otherwise
  2. If a sufficiently high /warnversion (>= 5) is enabled, we run the strong version of analysis, and a. If it reports no diagnostics, we are done. b. If it reports diagnostics, we run the weak version of analysis. Errors that are common to the two runs are reported as errors, and errors only reported by the strong version are downgraded to a warning.
  3. Otherwise we run the weak version of analysis.

Future record direction

See https://github.com/dotnet/csharplang/issues/3707 for the full list. We briefly went through the list here to gauge support from LDT members on the various proposals. We didn't get particularly in depth on any one part, but some highlights:

  • init fields and methods - We rejected these in 9, deciding to wait for community feedback. We believe this is still the right decision, and want to hear user scenarios before proceeding further.
  • Final initializers - We briefly entertained the idea of having an init { } syntax to guarantee that a block is called after a method. This was later rejected as too complicated after design review. Like init, we need to get a better handle on the user scenarios.
  • Required members - We have broad support for doing something in this space.
  • Factores - We have broad support for doing something in this space.
  • User-defined cloning - Will likely need to be designed hand-in-hand with factories
  • Cross-inheritance between records and non-records - part of the initial record goal was that record is pure syntactic sugar. If that's still a goal, then we need to do more work here.
  • Generalized primary constructors - Mixed support here. We need to do more design work.
  • Primary constructor bodies - Might be done for the former. We need to flesh this out so we can determine how to apply attributes to record constructors.
  • Discriminated unions - We need to determine whether this will be a simple syntactic shorthand for a general sealed type hierarchy feature, or if this will be the only way to declare such hierarchies.