csharpstandard icon indicating copy to clipboard operation
csharpstandard copied to clipboard

Grammar rule *parameter_modifier* disallows valid V7 constructs

Open RexJaeschke opened this issue 1 year ago • 4 comments

[I stumbled on this today while looking at how to spec the addition of scoped to a parameter for a future version.]

The relevant grammar for method parameters in §15.6.2.1 is, as follows:

fixed_parameter
    : attributes? parameter_modifier? type identifier default_argument?
    ;

parameter_modifier
    : parameter_mode_modifier
    | 'this'
    ;

parameter_mode_modifier
    : 'ref'
    | 'out'
    | 'in'
    ;

Rule parameter_modifier allows parameter_mode_modifier or this, but not both. However, two combinations of these are permitted, as follows:

public static class E
{
    public static void F1b(this in int p) { }
    public static void F1d(this ref int p) { }
}

This possibility is supported by the text in §15.6.10 Extension methods, which states:

When the first parameter of a method includes the this modifier, that method is said to be an extension method. Extension methods shall only be declared in non-generic, non-nested static classes. The first parameter of an extension method is restricted, as follows:

  • It may only be an input parameter if it has a value type
  • It may only be a reference parameter if it has a value type or has a generic type constrained to struct
  • It shall not be a pointer type.

I propose the following grammar change:

parameter_modifier
    : parameter_mode_modifier
    | 'this' parameter_mode_modifier?
    ;

Now this new grammar also allows this out, which according to my compiler is not permitted [CS8328], and that suggests we also add to the extension bullet list above, the following constraint:

  • It shall not be an output parameter.

RexJaeschke avatar Nov 17 '24 17:11 RexJaeschke

Re my second suggestion, I just found the following in §15.6.2.1:

If the parameter is a struct type or a type parameter constrained to a struct, the this modifier may be combined with either the ref or in modifier, but not the out modifier. Extension methods are further described in §15.6.10.

That said, having the new bullet I proposed clarifies it at the parameter end of the call in the case of extension methods, which are not singled out by the above quote.

RexJaeschke avatar Nov 17 '24 19:11 RexJaeschke

Can we rename parameter_modifier to parameter_modifiers? It doesn't feel like this ref is a single parameter modifier. This is purely a stylistic thing, and I'm happy to be overruled.

I'll vote against on this one – not because I think the current naming in this area is good, it isn’t really, but because making it plural won’t make it any better so stick with the status quo.

Nigel-Ecma avatar Nov 20 '24 09:11 Nigel-Ecma

Note for the February meeting: this PR has not changed (as far as I can see) since November.

jskeet avatar Feb 18 '25 10:02 jskeet

(Closure was accidental.)

jskeet avatar Feb 18 '25 10:02 jskeet

closed/reopened to run all checks

RexJaeschke avatar May 29 '25 20:05 RexJaeschke

@Nigel-Ecma I made no change re your suggestion in https://github.com/dotnet/csharpstandard/pull/1209#pullrequestreview-2446808223. Feel free to add a note in a separate PR.

RexJaeschke avatar May 29 '25 21:05 RexJaeschke