-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Extensions: fix lowering of implicit conversion on receiver in pattern-based scenarios #78685
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
Changes from 2 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 |
---|---|---|
|
@@ -1136,6 +1136,24 @@ private CompoundUseSiteInfo<AssemblySymbol> GetNewCompoundUseSiteInfo() | |
return new CompoundUseSiteInfo<AssemblySymbol>(_diagnostics, _compilation.Assembly); | ||
} | ||
|
||
private BoundExpression ConvertReceiverForExtensionMemberIfNeeded(Symbol member, BoundExpression receiver) | ||
{ | ||
if (member.GetIsNewExtensionMember()) | ||
{ | ||
Debug.Assert(!member.IsStatic); | ||
ParameterSymbol? extensionParameter = member.ContainingType.ExtensionParameter; | ||
Debug.Assert(extensionParameter is not null); | ||
#if DEBUG | ||
var discardedUseSiteInfo = CompoundUseSiteInfo<AssemblySymbol>.Discarded; | ||
Debug.Assert(Conversions.IsValidExtensionMethodThisArgConversion(this._compilation.Conversions.ClassifyConversionFromType(receiver.Type, extensionParameter.Type, isChecked: false, ref discardedUseSiteInfo))); | ||
#endif | ||
|
||
return MakeConversionNode(receiver, extensionParameter.Type, @checked: false, acceptFailingConversion: false, markAsChecked: 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. I do not see any corresponding changes in binding, therefore, I am not certain whether we really can pass 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. Whenever initial binding produces the nodes for an extension property access, we go through 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 would like to suggest the following:
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 looks suspicious. #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. Only implicit conversions are allowed on the receiver of the extension member. Implicit conversions don't care about checked/unchecked (only certain operators and explicit conversions care) 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 capturing this line of thinking in a comment. |
||
} | ||
|
||
return receiver; | ||
} | ||
|
||
#if DEBUG | ||
/// <summary> | ||
/// Note: do not use a static/singleton instance of this type, as it holds state. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -702,7 +702,7 @@ private BoundExpression MakeObjectInitializerMemberAccess( | |
_compilation.Conversions.HasImplicitConversionToOrImplementsVarianceCompatibleInterface(rewrittenReceiver.Type, memberSymbol.ContainingType, ref discardedUseSiteInfo, out _)); | ||
// It is possible there are use site diagnostics from the above, but none that we need report as we aren't generating code for the conversion | ||
#endif | ||
rewrittenReceiver = _factory.ConvertReceiverForExtensionMemberIfNeeded(memberSymbol, rewrittenReceiver); | ||
rewrittenReceiver = this.ConvertReceiverForExtensionMemberIfNeeded(memberSymbol, rewrittenReceiver); | ||
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. I was not able to find one.
The |
||
|
||
switch (memberSymbol.Kind) | ||
{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -431,24 +431,6 @@ public BoundExpression AssignmentExpression(BoundExpression left, BoundExpressio | |
return AssignmentExpression(Syntax, left, right, isRef: isRef, wasCompilerGenerated: true); | ||
} | ||
|
||
public BoundExpression ConvertReceiverForExtensionMemberIfNeeded(Symbol member, BoundExpression receiver) | ||
{ | ||
if (member.GetIsNewExtensionMember()) | ||
{ | ||
Debug.Assert(!member.IsStatic); | ||
ParameterSymbol? extensionParameter = member.ContainingType.ExtensionParameter; | ||
Debug.Assert(extensionParameter is not null); | ||
#if DEBUG | ||
var discardedUseSiteInfo = CompoundUseSiteInfo<AssemblySymbol>.Discarded; | ||
Debug.Assert(Conversions.IsValidExtensionMethodThisArgConversion(this.Compilation.Conversions.ClassifyConversionFromType(receiver.Type, extensionParameter.Type, isChecked: false, ref discardedUseSiteInfo))); | ||
#endif | ||
|
||
return this.Convert(extensionParameter.Type, receiver); | ||
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. 📝 the problem was that this produces a |
||
} | ||
|
||
return receiver; | ||
} | ||
|
||
/// <summary> | ||
/// Creates a general assignment that might be instrumented. | ||
/// </summary> | ||
|
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.
📝 I was debugging in this area as part of this PR and noticed we're doing some captures