Skip to content

Extensions: record decisions from LDM #9315

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
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
15 changes: 8 additions & 7 deletions proposals/extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ Types and aliases may not be named "extension".

### Nullability

- Confirm the current design, ie. maximal portability/compatibility
- ~~Confirm the current design, ie. maximal portability/compatibility~~ (answer: yes, LDM 2025-04-17)

```csharp
extension([System.Diagnostics.CodeAnalysis.DoesNotReturnIf(false)] bool b)
Expand All @@ -515,9 +515,9 @@ Types and aliases may not be named "extension".

### Metadata

- Should skeleton methods throw `NotSupportedException` or some other standard exception (right now we do `throw null;`)?
- Should we accept more than one parameter in marker method in metadata (in case new versions add more info)?
- Should the extension marker or speakable implementation methods be marked with special name?
- ~~Should skeleton methods throw `NotSupportedException` or some other standard exception (right now we do `throw null;`)?~~ (answer: yes, LDM 2025-04-17)
- ~~Should we accept more than one parameter in marker method in metadata (in case new versions add more info)?~~ (answer: we can remain strict, LDM 2025-04-17)
- ~~Should the extension marker or speakable implementation methods be marked with special name?~~ (answer: the marker method should be marked with special name and we should check it, but not implementation methods, LDM 2025-04-17)
- ~~Should we add `[Extension]` attribute on the static class even when there is no instance extension method inside?~~ (answer: yes, LDM 2025-03-10)
- ~~Confirm we should add `[Extension]` attribute to implementation getters and setters too.~~ (answer: no, LDM 2025-03-10)

Expand All @@ -531,7 +531,7 @@ Types and aliases may not be named "extension".
- ~~How to resolve static extension methods?~~ (answer: just like instance extension methods, LDM 2025-03-03)
- ~~How to resolve properties?~~ (answered in broad strokes LDM 2025-03-03, but needs follow-up for betterness)
- ~~Scoping and shadowing rules for extension parameter and type parameters~~ (answer: in scope of extension block, shadowing disallowed, LDM 2025-03-10)
- How should ORPA apply to new extension methods?
- ~~How should ORPA apply to new extension methods?~~ (answer: treat extension blocks as transparent, the "containing type" for ORPA is the enclosing static class, LDM 2025-04-17)

```
public static class Extensions
Expand Down Expand Up @@ -615,11 +615,12 @@ static class E
}
}
```
- Revisit question of lookup on type parameter ([discussion](https://github.com/dotnet/csharplang/discussions/8696#discussioncomment-12817547))

### Accessibility

- ~~What is the meaning of accessibility within an extension declaration?~~ (answer: extension declarations do not count as an accessibility scope, LDM 2025-03-17)
- Should we apply the "inconsistent accessibility" check on the receiver parameter even for static members?
- ~~Should we apply the "inconsistent accessibility" check on the receiver parameter even for static members?~~ (answer: yes, LDM 2025-04-17)
```csharp
public static class Extensions
{
Expand All @@ -640,7 +641,7 @@ public static class Extensions

- ~~Should we relax the type parameter validation (inferrability: all the type parameters must appear in the type of the extension parameter) where there are only methods? This would allow porting 100% of classic extension methods.
If you have `TResult M<TResult, TSource>(this TSource source)`, you could port it as `extension<TResult, TSource>(TSource source) { TResult M() ... }`.~~ (answer: no, LDM 2025-03-17)
- Confirm whether init-only accessors should be allowed in extensions
- ~~Confirm whether init-only accessors should be allowed in extensions~~ (answer: okay to disallow for now, LDM 2025-04-17)
- ~~Should the only difference in receiver ref-ness be allowed `extension(int receiver) { public void M2() {} }` `extension(ref int receiver) { public void M2() {} }`?~~ (answer: no, keep spec'ed rule, LDM 2025-03-24)
- ~~Should we complain about a conflict like this `extension(object receiver) { public int P1 => 1; }` `extension(object receiver) { public int P1 {set{}} }`?~~ (answer: yes, keep spec'ed rule, LDM 2025-03-24)
- ~~Should we complain about conflicts between skeleton methods that aren't conflicts between implementation methods?~~ (answer: yes, keep spec'ed rule, LDM 2025-03-24)
Expand Down