Skip to content

Latest commit

 

History

History
65 lines (46 loc) · 4.1 KB

LDM-2022-05-09.md

File metadata and controls

65 lines (46 loc) · 4.1 KB

C# Language Design Meeting for May 9th, 2022

Agenda

  1. Numeric IntPtr
  2. Ref readonly parameters

Quote of the Day

  • "Not all Unsafe is created equal"

Discussion

Numeric IntPtr

#6065

This C# change is mostly a reaction to a change in the BCL's thinking around IntPtr, and how generic math will apply to it. During the design of nint, we wanted to keep nint and IntPtr as distinct as possible, as the intent was not to enable general math on IntPtrs. However, as the BCL has rationalized their generic math designs, they've decided that the easiest way forward will be to remove this distinction, and enable generic math on IntPtr. We therefore want to update C# to similarly remove the distinction, and regard nint as simple alias for IntPtr (and nuint a simple alias for UIntPtr) to keep the language and runtime in sync.

Conclusion

Accepted.

Ref readonly parameters

#6010

We wanted to revisit the decision we made last time, as further discussion after the meeting revealed that we had conflated a few features in the decision, and we wanted to break them out and be sure that we are comfortable with feature. In particular, we did not explore the analyzer route enough, as further investigation revealed that, after the in/ref mismatch was dealt with, nothing prevented using an analyzer to prevent rvalues being passed to in parameters. There are 3 main components, therefore, that this proposal seeks to address:

  1. There is no way to move an existing API from ref to in without a source-breaking change. We addressed this issue by allowing ref to be used for in parameters, and did not discuss changing this today.
  2. At the declaration site, there is no way to indicate that being passed an rvalue from the call site is likely an error. This was our main discussion today.
  3. At the call site, lack of required in makes it unclear that a ref is being captured. This was not covered today, and we'll try to squeeze a discussion in next meeting.

On the surface, points 2 and 3 appear to be a good fit for an analyzer, but we think there might an opportunity to address a lingering annoyance from the original design of in parameters: the in keyword does not correspond to ref readonly, the keyword we use everywhere else throughout the language for a similar concept. We see an opportunity to retcon in to be a modifier with extra behavior on top of ref readonly, much like out is a modifier on top of ref with extra behavior on top. There is also the potential for an analyzer here to make the language more complex, not less, as now this spot in the table of declaration site modifiers/permitted call site forms would be taken by an analyzer, not by a native language feature.

The history of in as a feature stretches back to the time some members of the LDT spent on the Midori project, where they had a custom version of C# that supported a number of features, including a version of ref readonly. Initially, they used ref readonly as both the declaration site and the call site modifier, but user feedback, particularly on the call site side, was immediate and vocal. To combat this, they brainstormed and settled on in (first just at the call site, then eventually as a parameter modifier), as it's the natural counterpart to out and has been used as a C# keyword since C# 1.0. This was then brought into C# in the C# 7 timeframe, as we added ref structs based on Midori's experience in the area. Midori, however, didn't have as many of these APIs where passing an rvalue was incorrect, as it had an expanded permissions system for lifetime control. C# does not have this, so we think that ref readonly is a good change to make up for this.

Next, we will look at how ref readonly should affect the call site, and whether it should require that ref, in, or some other specifier to be explicitly provided.

Conclusion

We upload the decision around ref readonly as a parameter modifier.