Skip to content

Commit

Permalink
Final prototype comments and top level statements local adjustments (#…
Browse files Browse the repository at this point in the history
…61551)

Clean up the last of the prototype comments and adjust the parsing of locals named required in top level statements.
  • Loading branch information
333fred authored May 27, 2022
1 parent 7c0a0e5 commit 8452ec2
Show file tree
Hide file tree
Showing 8 changed files with 423 additions and 302 deletions.
13 changes: 13 additions & 0 deletions docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md
Original file line number Diff line number Diff line change
Expand Up @@ -391,3 +391,16 @@ Console.WriteLine($"{{{12:X}}}");
The workaround is to remove the extra braces in the format string.

You can learn more about this change in the associated [roslyn issue](https://github.com/dotnet/roslyn/issues/57750).

## Types cannot be named `required`

***Introduced in Visual Studio 2022 version 17.3.*** Starting in C# 11, types cannot be named `required`. The compiler will report an error on all such type names. To work around this, the type name and all usages must be escaped with an `@`:

```csharp
class required {} // Error CS9029
class @required {} // No error
```

This was done as `required` is now a member modifier for properties and fields.

You can learn more about this change in the associated [csharplang issue](https://github.com/dotnet/csharplang/issues/3630).
5 changes: 3 additions & 2 deletions docs/contributing/Compiler Test Plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ This document provides guidance for thinking about language interactions and tes
- Access modifiers (public, protected, internal, protected internal, private protected, private), static, ref
- type declarations (class, record class/struct with or without positional members, struct, interface, type parameter)
- methods
- fields
- properties (including get/set/init accessors)
- fields (required and not)
- properties (including get/set/init accessors, required and not)
- events (including add/remove accessors)
- Parameter modifiers (ref, out, in, params)
- Attributes (including generic attributes and security attributes)
Expand Down Expand Up @@ -110,6 +110,7 @@ This document provides guidance for thinking about language interactions and tes
- pre-processing directives
- COM interop
- modopt and modreq
- CompilerFeatureRequiredAttribute
- ref assemblies
- extern alias
- UnmanagedCallersOnly
Expand Down
34 changes: 16 additions & 18 deletions src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2070,26 +2070,24 @@ internal enum ErrorCode
ERR_ExpressionTreeContainsUTF8StringLiterals = 9027,
ERR_MisplacedUnchecked = 9028,

ERR_RequiredNameDisallowed = 9029,
ERR_OverrideMustHaveRequired = 9030,
ERR_RequiredMemberCannotBeHidden = 9031,
ERR_RequiredMemberCannotBeLessVisibleThanContainingType = 9032,
ERR_ExplicitRequiredMember = 9033,
ERR_RequiredMemberMustBeSettable = 9034,
ERR_RequiredMemberMustBeSet = 9035,
ERR_RequiredMembersMustBeAssignedValue = 9036,
ERR_RequiredMembersInvalid = 9037,
ERR_RequiredMembersBaseTypeInvalid = 9038,
ERR_ChainingToSetsRequiredMembersRequiresSetsRequiredMembers = 9039,
ERR_NewConstraintCannotHaveRequiredMembers = 9040,
ERR_UnsupportedCompilerFeature = 9041,
WRN_ObsoleteMembersShouldNotBeRequired = 9042,
ERR_RefReturningPropertiesCannotBeRequired = 9043,

#endregion

// Note: you will need to re-generate compiler code after adding warnings (eng\generate-compiler-code.cmd)

// PROTOTYPE(req): Move above the comment and condense before merge

ERR_RequiredNameDisallowed = 9500,
ERR_OverrideMustHaveRequired = 9501,
ERR_RequiredMemberCannotBeHidden = 9502,
ERR_RequiredMemberCannotBeLessVisibleThanContainingType = 9503,
ERR_ExplicitRequiredMember = 9504,
ERR_RequiredMemberMustBeSettable = 9505,
ERR_RequiredMemberMustBeSet = 9506,
ERR_RequiredMembersMustBeAssignedValue = 9507,
ERR_RequiredMembersInvalid = 9508,
ERR_RequiredMembersBaseTypeInvalid = 9509,
ERR_ChainingToSetsRequiredMembersRequiresSetsRequiredMembers = 9510,
ERR_NewConstraintCannotHaveRequiredMembers = 9511,
ERR_UnsupportedCompilerFeature = 9512,
WRN_ObsoleteMembersShouldNotBeRequired = 9513,
ERR_RefReturningPropertiesCannotBeRequired = 9514,
}
}
4 changes: 1 addition & 3 deletions src/Compilers/CSharp/Portable/Errors/MessageID.cs
Original file line number Diff line number Diff line change
Expand Up @@ -238,9 +238,6 @@ internal enum MessageID

IDS_FeatureGenericAttributes = MessageBase + 12812,

// PROTOTYPE(req): here for avoiding merge conflicts. Move to the end and condense before merge.
IDS_FeatureRequiredMembers = MessageBase + 13000,

IDS_FeatureNewLinesInInterpolations = MessageBase + 12813,
IDS_FeatureListPattern = MessageBase + 12814,
IDS_ParameterNullChecking = MessageBase + 12815,
Expand All @@ -257,6 +254,7 @@ internal enum MessageID
IDS_FeatureUnsignedRightShift = MessageBase + 12823,
IDS_FeatureExtendedNameofScope = MessageBase + 12824,
IDS_FeatureRelaxedShiftOperator = MessageBase + 12825,
IDS_FeatureRequiredMembers = MessageBase + 12826,
}

// Message IDs may refer to strings that need to be localized.
Expand Down
14 changes: 8 additions & 6 deletions src/Compilers/CSharp/Portable/Parser/LanguageParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1173,8 +1173,9 @@ internal static DeclarationModifiers GetModifier(SyntaxKind kind, SyntaxKind con
}
}

private void ParseModifiers(SyntaxListBuilder tokens, bool forAccessors)
private void ParseModifiers(SyntaxListBuilder tokens, bool forAccessors, bool forTopLevelStatements)
{
Debug.Assert(!(forAccessors && forTopLevelStatements));
while (true)
{
var newMod = GetModifier(this.CurrentToken);
Expand Down Expand Up @@ -1258,8 +1259,9 @@ private void ParseModifiers(SyntaxListBuilder tokens, bool forAccessors)
case DeclarationModifiers.Required:
// In C# 11, required in a modifier position is always a keyword if not escaped. Otherwise, we reuse the async detection
// machinery to make a conservative guess as to whether the user meant required to be a keyword, so that they get a good langver
// diagnostic and all the machinery to upgrade their project kicks in.
if (!IsFeatureEnabled(MessageID.IDS_FeatureRequiredMembers) && !ShouldAsyncOrRequiredBeTreatedAsModifier(parsingStatementNotDeclaration: false))
// diagnostic and all the machinery to upgrade their project kicks in. The only exception to this rule is top level statements,
// where the user could conceivably have a local named required. For these locations, we need to disambiguate as well.
if ((!IsFeatureEnabled(MessageID.IDS_FeatureRequiredMembers) || forTopLevelStatements) && !ShouldAsyncOrRequiredBeTreatedAsModifier(parsingStatementNotDeclaration: false))
{
return;
}
Expand Down Expand Up @@ -2373,7 +2375,7 @@ private MemberDeclarationSyntax ParseMemberDeclarationOrStatementCore(SyntaxKind
}

// All modifiers that might start an expression are processed above.
this.ParseModifiers(modifiers, forAccessors: false);
this.ParseModifiers(modifiers, forAccessors: false, forTopLevelStatements: true);
bool haveModifiers = (modifiers.Count > 0);
MemberDeclarationSyntax result;

Expand Down Expand Up @@ -2826,7 +2828,7 @@ private MemberDeclarationSyntax ParseMemberDeclarationCore(SyntaxKind parentKind
{
var attributes = this.ParseAttributeDeclarations();

this.ParseModifiers(modifiers, forAccessors: false);
this.ParseModifiers(modifiers, forAccessors: false, forTopLevelStatements: false);

// Check for constructor form
if (this.CurrentToken.Kind == SyntaxKind.IdentifierToken && this.PeekToken(1).Kind == SyntaxKind.OpenParenToken)
Expand Down Expand Up @@ -4120,7 +4122,7 @@ private AccessorDeclarationSyntax ParseAccessorDeclaration(bool isEvent)
try
{
var accAttrs = this.ParseAttributeDeclarations();
this.ParseModifiers(accMods, forAccessors: true);
this.ParseModifiers(accMods, forAccessors: true, forTopLevelStatements: false);

// check availability of readonly members feature for accessors
CheckForVersionSpecificModifiers(accMods, SyntaxKind.ReadOnlyKeyword, MessageID.IDS_FeatureReadOnlyMembers);
Expand Down
Loading

0 comments on commit 8452ec2

Please sign in to comment.