-
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 4 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. 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 |
---|---|---|
|
@@ -78,7 +78,7 @@ internal static void AddDelegateMembers( | |
symbols.Add(new BeginInvokeMethod(invoke, iAsyncResultType, objectType, asyncCallbackType, syntax)); | ||
|
||
// and (4) EndInvoke methods | ||
symbols.Add(new EndInvokeMethod(invoke, iAsyncResultType, syntax)); | ||
symbols.Add(new EndInvokeMethod(invoke, iAsyncResultType, syntax, binder, diagnostics)); | ||
} | ||
|
||
if (delegateType.DeclaredAccessibility <= Accessibility.Private) | ||
|
@@ -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 | ||
|
@@ -342,15 +356,18 @@ internal override OneOrMany<SyntaxList<AttributeListSyntax>> GetReturnTypeAttrib | |
|
||
private sealed class EndInvokeMethod : SourceDelegateMethodSymbol | ||
{ | ||
private readonly RefKind refKind; | ||
private readonly RefKind _refKind; | ||
private readonly ImmutableArray<CustomModifier> _refCustomModifiers; | ||
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 replacing two these members with a reference to |
||
|
||
internal EndInvokeMethod( | ||
InvokeMethod invoke, | ||
TypeSymbol iAsyncResultType, | ||
DelegateDeclarationSyntax syntax) | ||
DelegateDeclarationSyntax syntax, | ||
Binder binder, | ||
DiagnosticBag diagnostics) | ||
: base((SourceNamedTypeSymbol)invoke.ContainingType, invoke.ReturnType, syntax, MethodKind.Ordinary, DeclarationModifiers.Virtual | DeclarationModifiers.Public) | ||
{ | ||
this.refKind = invoke.RefKind; | ||
this._refKind = invoke.RefKind; | ||
|
||
var parameters = ArrayBuilder<ParameterSymbol>.GetInstance(); | ||
int ordinal = 0; | ||
|
@@ -366,6 +383,16 @@ internal EndInvokeMethod( | |
|
||
parameters.Add(SynthesizedParameterSymbol.Create(this, iAsyncResultType, ordinal++, RefKind.None, GetUniqueParameterName(parameters, "result"))); | ||
InitializeParameters(parameters.ToImmutableAndFree()); | ||
|
||
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.
It feels like we could simply reuse modifiers from the |
||
} | ||
else | ||
{ | ||
_refCustomModifiers = ImmutableArray<CustomModifier>.Empty; | ||
} | ||
} | ||
|
||
protected override SourceMethodSymbol BoundAttributesSource | ||
|
@@ -384,8 +411,10 @@ public override string Name | |
|
||
internal override RefKind RefKind | ||
{ | ||
get { return refKind; } | ||
get { return _refKind; } | ||
} | ||
|
||
public override ImmutableArray<CustomModifier> RefCustomModifiers => _refCustomModifiers; | ||
} | ||
|
||
private static string GetUniqueParameterName(ArrayBuilder<ParameterSymbol> currentParameters, string name) | ||
|
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) | ||
{ | ||
|
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.
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 comment
The reason will be displayed to describe this comment to others. Learn more.
Consider a similar scenario like
IsVolatileModfifierType
. Can we re-use that approach here? #ResolvedThere 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.
Unfortunately, no. Unless there is something I'm missing,
IsConst
is not a special library type :(In reply to: 117829472 [](ancestors = 117829472)
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.
Perhaps the same approach as
SymbolFactory.GetSystemTypeSymbol
. #ResolvedThere 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.
we need a bug or a PROTOTYPE marker to track this
In reply to: 117561528 [](ancestors = 117561528)
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.
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 comment
The 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 comment
The 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 comment
The reason will be displayed to describe this comment to others. Learn more.
Planning on fixing now.
In reply to: 117888944 [](ancestors = 117888944,117561528)
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.
From what I tracked down, it ends up doing a lookup in
NamespaceOrTypeSymbol
based on string comparison as well. Will separate the comparison to namespace/type pair to improve performance.In reply to: 117866143 [](ancestors = 117866143)