Skip to content

Commit 2109823

Browse files
committed
Extensions: fix lowering of implicit conversion on receiver in
pattern-based scenarios
1 parent c3c7ad6 commit 2109823

File tree

8 files changed

+503
-30
lines changed

8 files changed

+503
-30
lines changed

src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3026,13 +3026,13 @@ private bool CheckInvocationArgMixingWithUpdatedRules(
30263026
}
30273027
}
30283028

3029-
inferDeclarationExpressionValEscape();
3029+
inferDeclarationExpressionValEscape(argsOpt, localScopeDepth, escapeValues);
30303030

30313031
mixableArguments.Free();
30323032
escapeValues.Free();
30333033
return valid;
30343034

3035-
void inferDeclarationExpressionValEscape()
3035+
void inferDeclarationExpressionValEscape(ImmutableArray<BoundExpression> argsOpt, SafeContext localScopeDepth, ArrayBuilder<EscapeValue> escapeValues)
30363036
{
30373037
// find the widest scope that arguments could safely escape to.
30383038
// use this scope as the inferred STE of declaration expressions.

src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter.PatternLocalRewriter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ protected BoundExpression LowerEvaluation(BoundDagEvaluation evaluation)
152152
PropertySymbol property = p.Property;
153153
var outputTemp = new BoundDagTemp(p.Syntax, property.Type, p);
154154
BoundExpression output = _tempAllocator.GetTemp(outputTemp);
155-
input = _factory.ConvertReceiverForExtensionMemberIfNeeded(property, input);
155+
input = _localRewriter.ConvertReceiverForExtensionMemberIfNeeded(property, input);
156156
return _factory.AssignmentExpression(output, _localRewriter.MakePropertyAccess(_factory.Syntax, input, property, LookupResultKind.Viable, property.Type, isLeftOfAssignment: false));
157157
}
158158

@@ -191,7 +191,7 @@ void addArg(RefKind refKind, BoundExpression expression)
191191
addArg(RefKind.Out, _tempAllocator.GetTemp(outputTemp));
192192
}
193193

194-
receiver = _factory.ConvertReceiverForExtensionMemberIfNeeded(method, receiver);
194+
receiver = _localRewriter.ConvertReceiverForExtensionMemberIfNeeded(method, receiver);
195195
return _factory.Call(receiver, method, refKindBuilder.ToImmutableAndFree(), argBuilder.ToImmutableAndFree());
196196
}
197197

src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,6 +1136,24 @@ private CompoundUseSiteInfo<AssemblySymbol> GetNewCompoundUseSiteInfo()
11361136
return new CompoundUseSiteInfo<AssemblySymbol>(_diagnostics, _compilation.Assembly);
11371137
}
11381138

1139+
private BoundExpression ConvertReceiverForExtensionMemberIfNeeded(Symbol member, BoundExpression receiver)
1140+
{
1141+
if (member.GetIsNewExtensionMember())
1142+
{
1143+
Debug.Assert(!member.IsStatic);
1144+
ParameterSymbol? extensionParameter = member.ContainingType.ExtensionParameter;
1145+
Debug.Assert(extensionParameter is not null);
1146+
#if DEBUG
1147+
var discardedUseSiteInfo = CompoundUseSiteInfo<AssemblySymbol>.Discarded;
1148+
Debug.Assert(Conversions.IsValidExtensionMethodThisArgConversion(this._compilation.Conversions.ClassifyConversionFromType(receiver.Type, extensionParameter.Type, isChecked: false, ref discardedUseSiteInfo)));
1149+
#endif
1150+
1151+
return MakeConversionNode(receiver, extensionParameter.Type, @checked: false, acceptFailingConversion: false, markAsChecked: true);
1152+
}
1153+
1154+
return receiver;
1155+
}
1156+
11391157
#if DEBUG
11401158
/// <summary>
11411159
/// Note: do not use a static/singleton instance of this type, as it holds state.

src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_FixedStatement.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ private BoundStatement InitializeFixedStatementGetPinnable(
355355
}
356356

357357
// .GetPinnable()
358-
callReceiver = factory.ConvertReceiverForExtensionMemberIfNeeded(getPinnableMethod, callReceiver);
358+
callReceiver = this.ConvertReceiverForExtensionMemberIfNeeded(getPinnableMethod, callReceiver);
359359
var getPinnableCall = getPinnableMethod.IsStatic ?
360360
factory.Call(null, getPinnableMethod, callReceiver) :
361361
factory.Call(callReceiver, getPinnableMethod);

src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_ObjectOrCollectionInitializerExpression.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -702,7 +702,7 @@ private BoundExpression MakeObjectInitializerMemberAccess(
702702
_compilation.Conversions.HasImplicitConversionToOrImplementsVarianceCompatibleInterface(rewrittenReceiver.Type, memberSymbol.ContainingType, ref discardedUseSiteInfo, out _));
703703
// 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
704704
#endif
705-
rewrittenReceiver = _factory.ConvertReceiverForExtensionMemberIfNeeded(memberSymbol, rewrittenReceiver);
705+
rewrittenReceiver = this.ConvertReceiverForExtensionMemberIfNeeded(memberSymbol, rewrittenReceiver);
706706

707707
switch (memberSymbol.Kind)
708708
{

src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -431,24 +431,6 @@ public BoundExpression AssignmentExpression(BoundExpression left, BoundExpressio
431431
return AssignmentExpression(Syntax, left, right, isRef: isRef, wasCompilerGenerated: true);
432432
}
433433

434-
public BoundExpression ConvertReceiverForExtensionMemberIfNeeded(Symbol member, BoundExpression receiver)
435-
{
436-
if (member.GetIsNewExtensionMember())
437-
{
438-
Debug.Assert(!member.IsStatic);
439-
ParameterSymbol? extensionParameter = member.ContainingType.ExtensionParameter;
440-
Debug.Assert(extensionParameter is not null);
441-
#if DEBUG
442-
var discardedUseSiteInfo = CompoundUseSiteInfo<AssemblySymbol>.Discarded;
443-
Debug.Assert(Conversions.IsValidExtensionMethodThisArgConversion(this.Compilation.Conversions.ClassifyConversionFromType(receiver.Type, extensionParameter.Type, isChecked: false, ref discardedUseSiteInfo)));
444-
#endif
445-
446-
return this.Convert(extensionParameter.Type, receiver);
447-
}
448-
449-
return receiver;
450-
}
451-
452434
/// <summary>
453435
/// Creates a general assignment that might be instrumented.
454436
/// </summary>

0 commit comments

Comments
 (0)