Skip to content

Latest commit

 

History

History
40 lines (26 loc) · 3.1 KB

LDM-2024-06-26.md

File metadata and controls

40 lines (26 loc) · 3.1 KB

C# Language Design Meeting for June 26th, 2024

Agenda

Quote of the Day

  • "You only get one first impression, unless you're like me and you forget things all the time."

Discussion

Extensions

Champion Issue: #5497
Format proposal: #8242

We spent today looking over the proposed format for static member translation for extension types. The format discussion revolves around how much compatibility we want to maintain with existing extension methods, and whether we want to force other languages to do explicit work to support them. There are two real extremes here:

  1. Completely require that non-C# languages must do work to support new extension types. This means putting modreqs on the types, or using CompilerFeatureRequired, to force compilers that don't understand to pretend those members don't exist. This would ensure that we don't have to support any amount of back-compat work with new extensions, but also means that we'd rule out a migration story entirely.
  2. Fully support usage in other compilers in static form with no changes. This would possibly mean that C# would need to support calling these extensions in static form as well; if an older C# compiler could see and understand these static members, and emit calls to them, then upgrading and not supporting calling in static form would be a breaking change. The advantage of this form would be compatibility with some older extension methods, and permit upgrading older static classes to extension types, which is an attractive ability.

After some discussion, we ended up pulling the extremes into separate parts; instance method extensions, and everything else. For everything else, LDM is strongly against allowing them to be called in static form by other languages unless they do the work to explicitly support that form. For instance methods (ie, static void M(this int i) methods today), we're very interested in allowing back-compat. This would mean a few concrete things for the proposal to go chase down:

  1. We would have to support calling these instance methods in both instance.M() and E.M(instance) form, since the latter is valid today for existing extension methods defined on a static type.
  2. There are some areas of extension type resolution that do not behave the same as extension method resolution today. Those areas will need to be overhauled.
  3. Signature uniqueness still needs to be explored. How would the E.M(instance) format behave when E has both void M() and static void M(Instance i) defined on it?

We want to take these questions back and look at how complicated they will be to solve before making a final decision on the migration story.

Conclusion

We will block consumption in other languages without explicit support for extension types for all extension members except instance members. For instance members, we will explore making the emit binary-compatible, and how much we will have to overhaul to get that to work, then come back and make a final decision on whether to block consumption.