-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Adding IsConst modreq on ref readonly signatures #19658
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -52,11 +52,16 @@ internal override Cci.PrimitiveTypeCode GetPrimitiveTypeCode(PEModuleSymbol modu | |
return type.PrimitiveTypeCode; | ||
} | ||
|
||
internal override bool IsVolatileModifierType(PEModuleSymbol moduleSymbol, TypeSymbol type) | ||
internal override bool IsAcceptedVolatileModifierType(PEModuleSymbol moduleSymbol, TypeSymbol type) | ||
{ | ||
return type.SpecialType == SpecialType.System_Runtime_CompilerServices_IsVolatile; | ||
} | ||
|
||
internal override bool IsAcceptedIsConstModifierType(TypeSymbol type) | ||
{ | ||
return type.IsWellKnownTypeIsConst(); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Comparing symbols by full name is probably not be the best way to do it. Looking up a better alternative. #Closed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider a similar scenario like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unfortunately, no. Unless there is something I'm missing, In reply to: 117829472 [](ancestors = 117829472) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps the same approach as There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems simple enough to fix now vs. needing a PROTOTYPE comment to fix later. #Resolved There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Given that this is not a SpecialType, I think name comparison is the only right way to do that. If performance is a concern we can compare type name and namespace names separately, then calling ToDisplayString won't be needed. #Closed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If going with name comparing, should definitely compare namespace/type name parts separately. I think ToDisplay will concat them every time In reply to: 118063143 [](ancestors = 118063143) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From what I tracked down, it ends up doing a lookup in In reply to: 117866143 [](ancestors = 117866143) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we simplify There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you please explain? caching what? this is not doing lookup, but rather checking the passed symbol for full name equality. In reply to: 118763594 [](ancestors = 118763594) |
||
|
||
internal override TypeSymbol GetSZArrayTypeSymbol(PEModuleSymbol moduleSymbol, TypeSymbol elementType, ImmutableArray<ModifierInfo<TypeSymbol>> customModifiers) | ||
{ | ||
if (elementType is UnsupportedMetadataTypeSymbol) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -63,7 +63,7 @@ public static bool HasRefOrOutParameter(this PropertySymbol property) | |
{ | ||
foreach (ParameterSymbol param in property.Parameters) | ||
{ | ||
if (param.RefKind != RefKind.None) | ||
if (param.RefKind == RefKind.Ref || param.RefKind == RefKind.Out) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Did you add a test backing this change? Could you point to the test(s)? #Closed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adding In reply to: 118061963 [](ancestors = 118061963) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I couldn't find the test, what file it should be in? In reply to: 118609191 [](ancestors = 118609191,118061963) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. File In reply to: 119789809 [](ancestors = 119789809,118609191,118061963) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correction: In reply to: 120218968 [](ancestors = 120218968,119789809,118609191,118061963) |
||
{ | ||
return true; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,8 +35,9 @@ internal static void CopyMethodCustomModifiers( | |
// have already been compared. | ||
MethodSymbol constructedSourceMethod = sourceMethod.ConstructIfGeneric(destinationMethod.TypeArguments); | ||
|
||
customModifiers = CustomModifiersTuple.Create(constructedSourceMethod.ReturnTypeCustomModifiers, | ||
destinationMethod.ReturnsByRef ? constructedSourceMethod.RefCustomModifiers : ImmutableArray<CustomModifier>.Empty); | ||
customModifiers = CustomModifiersTuple.Create( | ||
constructedSourceMethod.ReturnTypeCustomModifiers, | ||
destinationMethod.ReturnsByRef || destinationMethod.ReturnsByRefReadonly ? constructedSourceMethod.RefCustomModifiers : ImmutableArray<CustomModifier>.Empty); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Could we simply check if RefKind is None? #Closed |
||
|
||
parameters = CopyParameterCustomModifiers(constructedSourceMethod.Parameters, destinationMethod.Parameters, alsoCopyParamsModifier); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -231,7 +231,8 @@ internal override LexicalSortKey GetLexicalSortKey() | |
|
||
private sealed class InvokeMethod : SourceDelegateMethodSymbol | ||
{ | ||
private readonly RefKind refKind; | ||
private readonly RefKind _refKind; | ||
private readonly ImmutableArray<CustomModifier> _refCustomModifiers; | ||
|
||
internal InvokeMethod( | ||
SourceMemberContainerTypeSymbol delegateType, | ||
|
@@ -242,13 +243,14 @@ internal InvokeMethod( | |
DiagnosticBag diagnostics) | ||
: base(delegateType, returnType, syntax, MethodKind.DelegateInvoke, DeclarationModifiers.Virtual | DeclarationModifiers.Public) | ||
{ | ||
this.refKind = refKind; | ||
this._refKind = refKind; | ||
|
||
SyntaxToken arglistToken; | ||
var parameters = ParameterHelpers.MakeParameters( | ||
binder, this, syntax.ParameterList, out arglistToken, | ||
allowRefOrOut: true, | ||
allowThis: false, | ||
addIsConstModifier: true, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Are we testing presence of modifiers on EndInvoke and BeginInvoke? #Closed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed and modified tests In reply to: 119757863 [](ancestors = 119757863) |
||
diagnostics: diagnostics); | ||
|
||
if (arglistToken.Kind() == SyntaxKind.ArgListKeyword) | ||
|
@@ -259,6 +261,16 @@ internal InvokeMethod( | |
diagnostics.Add(ErrorCode.ERR_IllegalVarArgs, new SourceLocation(arglistToken)); | ||
} | ||
|
||
if (_refKind == RefKind.RefReadOnly) | ||
{ | ||
var isConstType = binder.GetWellKnownType(WellKnownType.System_Runtime_CompilerServices_IsConst, diagnostics, syntax.ReturnType); | ||
_refCustomModifiers = ImmutableArray.Create(CSharpCustomModifier.CreateRequired(isConstType)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Are we testing presence of modifiers on EndInvoke? #Closed |
||
} | ||
else | ||
{ | ||
_refCustomModifiers = ImmutableArray<CustomModifier>.Empty; | ||
} | ||
|
||
InitializeParameters(parameters); | ||
} | ||
|
||
|
@@ -269,7 +281,7 @@ public override string Name | |
|
||
internal override RefKind RefKind | ||
{ | ||
get { return refKind; } | ||
get { return _refKind; } | ||
} | ||
|
||
internal override LexicalSortKey GetLexicalSortKey() | ||
|
@@ -287,14 +299,16 @@ internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, | |
{ | ||
base.AfterAddingTypeMembersChecks(conversions, diagnostics); | ||
|
||
if (refKind == RefKind.RefReadOnly) | ||
if (_refKind == RefKind.RefReadOnly) | ||
{ | ||
var syntax = (DelegateDeclarationSyntax)SyntaxRef.GetSyntax(); | ||
DeclaringCompilation.EnsureIsReadOnlyAttributeExists(diagnostics, syntax.ReturnType.GetLocation(), modifyCompilationForRefReadOnly: true); | ||
} | ||
|
||
ParameterHelpers.EnsureIsReadOnlyAttributeExists(Parameters, diagnostics, modifyCompilationForRefReadOnly: true); | ||
} | ||
|
||
public override ImmutableArray<CustomModifier> RefCustomModifiers => _refCustomModifiers; | ||
} | ||
|
||
private sealed class BeginInvokeMethod : SourceDelegateMethodSymbol | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -167,6 +167,7 @@ private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsB | |
signatureBinder, this, syntax.ParameterList, out arglistToken, | ||
allowRefOrOut: true, | ||
allowThis: true, | ||
addIsConstModifier: IsVirtual || IsAbstract, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This should probably include checks for override and explicit implementation, those are virtual (in metadata terms) as well and the difference will be observable for cases when the target method cannot be found, etc. #Closed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
diagnostics: diagnostics); | ||
|
||
_lazyIsVararg = (arglistToken.Kind() == SyntaxKind.ArgListKeyword); | ||
|
@@ -320,11 +321,19 @@ private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsB | |
|
||
if ((object)overriddenMethod != null) | ||
{ | ||
CustomModifierUtils.CopyMethodCustomModifiers(overriddenMethod, this, out _lazyReturnType, | ||
out _lazyCustomModifiers, | ||
CustomModifierUtils.CopyMethodCustomModifiers(overriddenMethod, this, out _lazyReturnType, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Is it Ok to end up without IsCons modifier for overriding case (overriding method is technically virtual)? Do we have a test for scenario like that? #Closed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My understanding is that the overriding method should always copy the parent's modifiers (for CLR to consider it as an override). And if the overridden method is a C# 7.1 virtual method with a ref-readonly parameter or a return type, then it will have this modifier. In reply to: 118078081 [](ancestors = 118078081) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
For proper overriding we should match modifiers exactly. I guess we have to decide whether it is fine to override without modifier, or should that be an error. #Closed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. will keep the current behavior, and add a test to assert it. In reply to: 118420724 [](ancestors = 118420724) |
||
out _lazyCustomModifiers, | ||
out _lazyParameters, alsoCopyParamsModifier: true); | ||
} | ||
} | ||
else if (_refKind == RefKind.RefReadOnly) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I think this code should be moved before the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
{ | ||
var isConstType = withTypeParamsBinder.GetWellKnownType(WellKnownType.System_Runtime_CompilerServices_IsConst, diagnostics, syntax.ReturnType); | ||
|
||
_lazyCustomModifiers = CustomModifiersTuple.Create( | ||
typeCustomModifiers: ImmutableArray<CustomModifier>.Empty, | ||
refCustomModifiers: ImmutableArray.Create(CSharpCustomModifier.CreateRequired(isConstType))); | ||
} | ||
} | ||
else if ((object)_explicitInterfaceType != null) | ||
{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -273,6 +273,14 @@ private SourcePropertySymbol( | |
_lazyParameters = CustomModifierUtils.CopyParameterCustomModifiers(overriddenOrImplementedProperty.Parameters, _lazyParameters, alsoCopyParamsModifier: isOverride); | ||
} | ||
} | ||
else if (_refKind == RefKind.RefReadOnly) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Same comment as for methods, should move it before There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
{ | ||
var isConstType = bodyBinder.GetWellKnownType(WellKnownType.System_Runtime_CompilerServices_IsConst, diagnostics, syntax.Type); | ||
|
||
_customModifiers = CustomModifiersTuple.Create( | ||
ImmutableArray<CustomModifier>.Empty, | ||
ImmutableArray.Create(CSharpCustomModifier.CreateRequired(isConstType))); | ||
} | ||
|
||
if (!hasAccessorList) | ||
{ | ||
|
@@ -775,7 +783,7 @@ private DeclarationModifiers MakeModifiers(SyntaxTokenList modifiers, bool isExp | |
} | ||
|
||
private static ImmutableArray<ParameterSymbol> MakeParameters( | ||
Binder binder, SourcePropertySymbol owner, BaseParameterListSyntax parameterSyntaxOpt, DiagnosticBag diagnostics) | ||
Binder binder, SourcePropertySymbol owner, BaseParameterListSyntax parameterSyntaxOpt, DiagnosticBag diagnostics, bool addIsConstModifier) | ||
{ | ||
if (parameterSyntaxOpt == null) | ||
{ | ||
|
@@ -792,6 +800,7 @@ private static ImmutableArray<ParameterSymbol> MakeParameters( | |
binder, owner, parameterSyntaxOpt, out arglistToken, | ||
allowRefOrOut: false, | ||
allowThis: false, | ||
addIsConstModifier: addIsConstModifier, | ||
diagnostics: diagnostics); | ||
|
||
if (arglistToken.Kind() != SyntaxKind.None) | ||
|
@@ -1388,7 +1397,7 @@ private TypeSymbol ComputeType(Binder binder, BasePropertyDeclarationSyntax synt | |
private ImmutableArray<ParameterSymbol> ComputeParameters(Binder binder, BasePropertyDeclarationSyntax syntax, DiagnosticBag diagnostics) | ||
{ | ||
var parameterSyntaxOpt = GetParameterListSyntax(syntax); | ||
var parameters = MakeParameters(binder, this, parameterSyntaxOpt, diagnostics); | ||
var parameters = MakeParameters(binder, this, parameterSyntaxOpt, diagnostics, addIsConstModifier: IsVirtual || IsAbstract); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Same comment as for methods. #Closed |
||
HashSet<DiagnosticInfo> useSiteDiagnostics = null; | ||
|
||
foreach (ParameterSymbol param in parameters) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It feels like we might be losing an optimization for this case. #Closed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Took a look. We won't be loosing an optimization.
CSDiagnosticInfo.IsEmpty
will returnfalse
fornull
results. Therefore, it won't be initialized. I believe the changed code is simpler to read now.In reply to: 119753756 [](ancestors = 119753756)