Skip to content

Relax ordering constraints for parameter modifiers #23643

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

Merged
merged 10 commits into from
Jan 4, 2018

Conversation

alrz
Copy link
Member

@alrz alrz commented Dec 7, 2017

Customer scenario

We allow ref this in ref extension methods but not the other way around. That's wrong! We can't disallow ref this, but we should allow and prefer this ref.

Note: this is a bug fix change to C# 7.2 that would ship in 15.6, per discussion with LDM.

Bugs this fixes

Fixes dotnet/csharplang#1022 (per LDM 2017-12-04)

Workarounds, if any

Type ref this instead of this ref.

Risk

Performance impact

TBD

Is this a regression from a previous update?

No. This restriction was introduced when the ref extension method was implemented in C# 7.2 (15.5).

Root cause analysis

How was the bug found?

Reported by customer.

Copy link
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM Thanks

@jcouv
Copy link
Member

jcouv commented Dec 9, 2017

Tagging @VSadov as FYI. Although we hadn't discussed in (only ref), the same relaxation on ordering makes sense for in too (as this PR implements).

@@ -1517,7 +1517,7 @@ internal enum ErrorCode
ERR_TypeReserved = 8336,
ERR_RefExtensionMustBeValueTypeOrConstrainedToOne = 8337,
ERR_InExtensionMustBeValueType = 8338,
ERR_BadParameterModifiersOrder = 8339,
// ERR_BadParameterModifiersOrder = 8339,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// ERR_BadParameterModifiersOrder = 8339, [](start = 8, length = 41)

I would expect the error message to be removed from the .resx file

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would also add a small comment to explain why it was removed.


In reply to: 156157236 [](ancestors = 156157236)

@AlekseyTs
Copy link
Contributor

I would expect to see some tests that verify that the different order of modifiers is actually properly treated by the compiler, i.e. the parameter is actually treated as ref/in by the compiler in addition to not reporting the error.

@AlekseyTs
Copy link
Contributor

Done with review pass (iteration 1).

@VSadov
Copy link
Member

VSadov commented Dec 11, 2017

Yes, it applies equally to ‘ref’ and ‘in’ extensions.

@VSadov
Copy link
Member

VSadov commented Dec 11, 2017

Also need some tests for scenarios with possibly new behavior like:
“ref this ref”,
“ref this in”

Still an error, but for a different reason.

@alrz alrz force-pushed the mod-ordering-extensions branch from 640fadb to f4a4534 Compare December 13, 2017 22:05
// (10,36): error CS8339: The parameter modifier 'in' cannot be used after the modifier 'this'
// public static void Method4<T>(this in int i) { }
Diagnostic(ErrorCode.ERR_BadParameterModifiersOrder, "in").WithArguments("in", "this").WithLocation(10, 36));
CreateCompilationWithMscorlibAndSystemCore(test).GetDeclarationDiagnostics().Verify();
}
Copy link
Contributor

@OmarTawfik OmarTawfik Dec 18, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd use compilation.VerifyDiagnostics() for completeness. #Closed

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd also change the name of the test.


In reply to: 157593732 [](ancestors = 157593732)

Diagnostic(ErrorCode.ERR_BadExtensionAgg, "GenExtensions").WithLocation(12, 21));
}

[Fact]
public void BadParameterModifiers()
Copy link
Contributor

@OmarTawfik OmarTawfik Dec 18, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BadParameterModifiers [](start = 20, length = 21)

BadParameterModifiers [](start = 20, length = 21)

Can we change the test name to describe which modifiers are bad? #Closed

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest adding the opposite test scenarios as well:

  • Testing we produce an error on in this ref int i
  • Testing we produce an error on in this in int i

In reply to: 157594285 [](ancestors = 157594285)

@OmarTawfik
Copy link
Contributor

OmarTawfik commented Dec 18, 2017

    public void BadParameterModifiers_ThisWithRef()

Can we rename that test to be more descriptive? this is now testing producing errors on the containing type. #Closed


Refers to: src/Compilers/CSharp/Test/Syntax/Parsing/ParserErrorMessageTests.cs:3087 in e107ed1. [](commit_id = e107ed1, deletion_comment = False)

@@ -1965,6 +1965,26 @@ public static class Ext
Assert.Equal(RefKind.In, symbol.RefKind);
}

[Fact]
public void ParameterSymbolsRetrievedThroughSemanticModel_ModifierOrdering()
Copy link
Contributor

@OmarTawfik OmarTawfik Dec 18, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ParameterSymbolsRetrievedThroughSemanticModel_ModifierOrdering [](start = 20, length = 62)

ParameterSymbolsRetrievedThroughSemanticModel_ModifierOrdering [](start = 20, length = 62)

This title is misleading. The symbols are not retrieved through the semantic model. I suggest following what ParameterSymbolsRetrievedThroughSemanticModel_InExtensionMethods do. I also suggest separating this in and this ref. #Closed

Copy link
Contributor

@OmarTawfik OmarTawfik Dec 18, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That test is still useful, but I suggest moving it to the Symbols test project, and use CompileAndVerify() helper, making use of the symbolValidator and sourceSymbolValidator parameters to check for the symbols.


In reply to: 157595248 [](ancestors = 157595248)

@OmarTawfik OmarTawfik self-assigned this Dec 18, 2017
Copy link
Contributor

@OmarTawfik OmarTawfik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @alrz for taking care of this!
Left a few comments.

@alrz alrz force-pushed the mod-ordering-extensions branch from f4a4534 to 57cc5bc Compare December 19, 2017 12:18
@alrz alrz force-pushed the mod-ordering-extensions branch from 57cc5bc to 547f4fe Compare December 19, 2017 12:22
@@ -3505,7 +3458,7 @@ public class TestType

[Fact]
[CompilerTrait(CompilerFeature.ReadOnlyReferences)]
public void BadInWithThisParameterModifiers()
public void InWithThis_ParameterModifiers()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need this test now. VerifyDiagnostics is called on the same combination of modifiers elsewhere.
But if we do want to keep this, it should be moved to another file.

Copy link
Contributor

@OmarTawfik OmarTawfik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

}

CompileAndVerify(source, validator: Validator, options: TestOptions.ReleaseDll).VerifyDiagnostics();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: for these two methods, CompileAndVerify will throw if there are any errors, so the trailing VerifyDiagnostics() is not needed.
However, you might want to make these tests actually print something through the extension methods, and use expectedOutput: "XX" parameter to verify the result.

@jcouv
Copy link
Member

jcouv commented Jan 2, 2018

@MeiChin-Tsai for ask-mode approval for 15.6. Thanks

@MeiChin-Tsai
Copy link

approved.

@jcouv jcouv merged commit adbce76 into dotnet:master Jan 4, 2018
@alrz alrz deleted the mod-ordering-extensions branch January 4, 2018 23:10
@jcouv jcouv added the Community The pull request was submitted by a contributor who is not a Microsoft employee. label Jan 9, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Compilers Community The pull request was submitted by a contributor who is not a Microsoft employee. Pending director approval
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Discussion: ref this vs this ref in ref extension methods (15.6, as a 7.2 bug fix)
6 participants