Skip to content
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

Dont suggest this in static local functions #35822

14 changes: 7 additions & 7 deletions src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -246,9 +246,9 @@ private BoundExpression CheckValue(BoundExpression expr, BindValueKind valueKind

// Since we have a concrete member in hand, we can resolve the receiver.
var typeOrValue = (BoundTypeOrValueExpression)receiver;
receiver = otherSymbol.IsStatic
? null // no receiver required
: typeOrValue.Data.ValueExpression;
receiver = otherSymbol.RequiresInstanceReceiver()
? typeOrValue.Data.ValueExpression
: null; // no receiver required
}
return new BoundBadExpression(
expr.Syntax,
Expand Down Expand Up @@ -868,7 +868,7 @@ private bool CheckIsValidReceiverForVariable(SyntaxNode node, BoundExpression re
/// </remarks>
private static bool RequiresVariableReceiver(BoundExpression receiver, Symbol symbol)
{
return !symbol.IsStatic
return symbol.RequiresInstanceReceiver()
&& symbol.Kind != SymbolKind.Event
&& receiver?.Type?.IsValueType == true;
}
Expand Down Expand Up @@ -1114,7 +1114,7 @@ bool isRefEscape
//• the safe-to-escape of all argument expressions(including the receiver)
//

if (symbol.IsStatic)
if (!symbol.RequiresInstanceReceiver())
{
// ignore receiver when symbol is static
receiverOpt = null;
Expand Down Expand Up @@ -1221,7 +1221,7 @@ bool isRefEscape
// o no ref or out argument(excluding the receiver and arguments of ref-like types) may have a narrower ref-safe-to-escape than E1; and
// o no argument(including the receiver) may have a narrower safe-to-escape than E1.

if (symbol.IsStatic)
if (!symbol.RequiresInstanceReceiver())
{
// ignore receiver when symbol is static
receiverOpt = null;
Expand Down Expand Up @@ -1327,7 +1327,7 @@ private static bool CheckInvocationArgMixing(
// - If there is a ref or out argument of a ref struct type (including the receiver), with safe-to-escape E1, then
// - no argument (including the receiver) may have a narrower safe-to-escape than E1.

if (symbol.IsStatic)
if (!symbol.RequiresInstanceReceiver())
{
// ignore receiver when symbol is static
receiverOpt = null;
Expand Down
4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/Binder/Binder_Conversions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ private BoundMethodGroup FixMethodGroupWithTypeOrValue(BoundMethodGroup group, C
BoundExpression receiverOpt = group.ReceiverOpt;
Debug.Assert(receiverOpt != null);
Debug.Assert((object)conversion.Method != null);
receiverOpt = ReplaceTypeOrValueReceiver(receiverOpt, conversion.Method.IsStatic && !conversion.IsExtensionMethod, diagnostics);
receiverOpt = ReplaceTypeOrValueReceiver(receiverOpt, !conversion.Method.RequiresInstanceReceiver && !conversion.IsExtensionMethod, diagnostics);
return group.Update(
group.TypeArgumentsOpt,
group.Name,
Expand Down Expand Up @@ -599,7 +599,7 @@ private bool MemberGroupFinalValidationAccessibilityChecks(BoundExpression recei
// None of the checks below apply if the receiver can't be classified as a type or value.
Debug.Assert(!invokedAsExtensionMethod);
}
else if (memberSymbol.IsStatic)
else if (!memberSymbol.RequiresInstanceReceiver())
{
Debug.Assert(!invokedAsExtensionMethod || (receiverOpt != null));

Expand Down
6 changes: 3 additions & 3 deletions src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1672,7 +1672,7 @@ private BoundExpression SynthesizeReceiver(SyntaxNode node, Symbol member, Diagn
// accessor, the result is the same as a member access of the form this.I. This can only
// happen when K is zero.

if (member.IsStatic)
if (!member.RequiresInstanceReceiver())
{
return null;
}
Expand Down Expand Up @@ -1737,7 +1737,7 @@ internal Symbol ContainingMember()

private BoundExpression TryBindInteractiveReceiver(SyntaxNode syntax, Symbol currentMember, NamedTypeSymbol currentType, NamedTypeSymbol memberDeclaringType)
{
if (currentType.TypeKind == TypeKind.Submission && !currentMember.IsStatic)
if (currentType.TypeKind == TypeKind.Submission && currentMember.RequiresInstanceReceiver())
{
if (memberDeclaringType.TypeKind == TypeKind.Submission)
{
Expand Down Expand Up @@ -6650,7 +6650,7 @@ private bool CheckInstanceOrStatic(
{
bool? instanceReceiver = IsInstanceReceiver(receiver);

if (symbol.IsStatic)
if (!symbol.RequiresInstanceReceiver())
{
if (instanceReceiver == true)
{
Expand Down
10 changes: 5 additions & 5 deletions src/Compilers/CSharp/Portable/Binder/Binder_Invocation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1002,7 +1002,7 @@ private BoundCall BindInvocationExpressionContinued(
// instance methods. Therefore we must detect this scenario here, rather than in
// overload resolution.

var receiver = ReplaceTypeOrValueReceiver(methodGroup.Receiver, method.IsStatic && !invokedAsExtensionMethod, diagnostics);
var receiver = ReplaceTypeOrValueReceiver(methodGroup.Receiver, !method.RequiresInstanceReceiver && !invokedAsExtensionMethod, diagnostics);

// Note: we specifically want to do final validation (7.6.5.1) without checking delegate compatibility (15.2),
// so we're calling MethodGroupFinalValidation directly, rather than via MethodGroupConversionHasErrors.
Expand Down Expand Up @@ -1056,7 +1056,7 @@ private BoundCall BindInvocationExpressionContinued(
// For extension methods, there is no receiver because the receiver in source was actually the first argument.
// For instance methods, we may have synthesized an implicit this node. We'll keep it for the emitter.
// For static methods, we may have synthesized a type expression. It serves no purpose, so we'll drop it.
if (invokedAsExtensionMethod || (method.IsStatic && receiver != null && receiver.WasCompilerGenerated))
if (invokedAsExtensionMethod || (!method.RequiresInstanceReceiver && receiver != null && receiver.WasCompilerGenerated))
{
receiver = null;
}
Expand All @@ -1065,7 +1065,7 @@ private BoundCall BindInvocationExpressionContinued(
var argRefKinds = analyzedArguments.RefKinds.ToImmutableOrNull();
var args = analyzedArguments.Arguments.ToImmutable();

if (!gotError && !method.IsStatic && receiver != null && receiver.Kind == BoundKind.ThisReference && receiver.WasCompilerGenerated)
if (!gotError && method.RequiresInstanceReceiver && receiver != null && receiver.Kind == BoundKind.ThisReference && receiver.WasCompilerGenerated)
{
gotError = IsRefOrOutThisParameterCaptured(node, diagnostics);
}
Expand Down Expand Up @@ -1116,7 +1116,7 @@ private BoundCall BindInvocationExpressionContinued(
bool isDelegateCall = (object)delegateTypeOpt != null;
if (!isDelegateCall)
{
if (!method.IsStatic)
if (method.RequiresInstanceReceiver)
{
WarnOnAccessOfOffDefault(node.Kind() == SyntaxKind.InvocationExpression ?
((InvocationExpressionSyntax)node).Expression :
Expand Down Expand Up @@ -1145,7 +1145,7 @@ ContainingMemberOrLambda is MethodSymbol containingMethod &&
// Ignore calls to base members.
TypeSymbol.Equals(containingMethod.ContainingType, method.ContainingType, TypeCompareKind.ConsiderEverything) &&
!method.IsEffectivelyReadOnly &&
!method.IsStatic)
method.RequiresInstanceReceiver)
{
Error(diagnostics, ErrorCode.WRN_ImplicitCopyInReadOnlyMember, receiver.Syntax, method, ThisParameterSymbol.SymbolName);
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ private static bool IsSymbolAccessibleCore(
case SymbolKind.Property:
case SymbolKind.Event:
case SymbolKind.Field:
if (symbol.IsStatic)
if (!symbol.RequiresInstanceReceiver())
{
// static members aren't accessed "through" an "instance" of any type. So we
// null out the "through" instance here. This ensures that we'll understand
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ private static Conversion ToConversion(OverloadResolutionResult<MethodSymbol> re
}

//cannot capture stack-only types.
if (!method.IsStatic && methodGroup.Receiver?.Type?.IsRestrictedType() == true)
if (method.RequiresInstanceReceiver && methodGroup.Receiver?.Type?.IsRestrictedType() == true)
{
return Conversion.NoConversion;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ private void RemoveStaticInstanceMismatches<TMember>(
{
var result = results[f];
TMember member = result.Member;
if (result.Result.IsValid && member.IsStatic != keepStatic)
if (result.Result.IsValid && member.RequiresInstanceReceiver() == keepStatic)
{
results[f] = new MemberResolutionResult<TMember>(member, result.LeastOverriddenMember, MemberAnalysisResult.StaticInstanceMismatch());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -608,9 +608,11 @@ private bool HadStaticInstanceMismatch(
else
{
ErrorCode errorCode =
symbol.IsStatic ? ErrorCode.ERR_ObjectProhibited :
Binder.WasImplicitReceiver(receiverOpt) && binder.InFieldInitializer && !binder.BindingTopLevelScriptCode ? ErrorCode.ERR_FieldInitRefNonstatic :
ErrorCode.ERR_ObjectRequired;
symbol.RequiresInstanceReceiver()
? Binder.WasImplicitReceiver(receiverOpt) && binder.InFieldInitializer && !binder.BindingTopLevelScriptCode
? ErrorCode.ERR_FieldInitRefNonstatic
: ErrorCode.ERR_ObjectRequired
: ErrorCode.ERR_ObjectProhibited;
// error CS0176: Member 'Program.M(B)' cannot be accessed with an instance reference; qualify it with a type name instead
// -or-
// error CS0120: An object reference is required for the non-static field, method, or property 'Program.M(B)'
Expand Down
4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1479,7 +1479,7 @@ private void EmitCallExpression(BoundCall call, UseKind useKind)

CallKind callKind;

if (method.IsStatic)
if (!method.RequiresInstanceReceiver)
{
callKind = CallKind.Call;
}
Expand Down Expand Up @@ -1748,7 +1748,7 @@ private static int GetCallStackBehavior(BoundCall call)
stack += 1;
}

if (!call.Method.IsStatic)
if (call.Method.RequiresInstanceReceiver)
{
// The call pops the receiver off the stack.
stack -= 1;
Expand Down
2 changes: 1 addition & 1 deletion src/Compilers/CSharp/Portable/CodeGen/Optimizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1107,7 +1107,7 @@ public override BoundNode VisitCall(BoundCall node)
// matches or a bit stronger than EmitReceiverRef
// if there are any doubts that receiver is a ref type,
// assume we will need an address (that will prevent scheduling of receiver).
if (!node.Method.IsStatic)
if (node.Method.RequiresInstanceReceiver)
{
receiver = VisitCallReceiver(receiver);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1139,7 +1139,7 @@ private void VisitReceiverBeforeCall(BoundExpression receiverOpt, MethodSymbol m
private void VisitReceiverAfterCall(BoundExpression receiverOpt, MethodSymbol method)
{
NamedTypeSymbol containingType;
if (receiverOpt != null && ((object)method == null || method.MethodKind == MethodKind.Constructor || (object)(containingType = method.ContainingType) != null && !method.IsStatic && !containingType.IsReferenceType && !TypeIsImmutable(containingType)))
if (receiverOpt != null && ((object)method == null || method.MethodKind == MethodKind.Constructor || (object)(containingType = method.ContainingType) != null && method.RequiresInstanceReceiver && !containingType.IsReferenceType && !TypeIsImmutable(containingType)))
{
WriteArgument(receiverOpt, method?.MethodKind == MethodKind.Constructor ? RefKind.Out : RefKind.Ref, method);
}
Expand Down Expand Up @@ -1296,7 +1296,7 @@ public override BoundNode VisitDelegateCreationExpression(BoundDelegateCreationE
var methodGroup = node.Argument as BoundMethodGroup;
if (methodGroup != null)
{
if ((object)node.MethodOpt != null && !node.MethodOpt.IsStatic)
if ((object)node.MethodOpt != null && node.MethodOpt.RequiresInstanceReceiver)
{
if (_trackRegions)
{
Expand Down Expand Up @@ -1377,7 +1377,7 @@ public override BoundNode VisitConversion(BoundConversion node)
{
if (node.ConversionKind == ConversionKind.MethodGroup)
{
if (node.IsExtensionMethod || ((object)node.SymbolOpt != null && !node.SymbolOpt.IsStatic))
if (node.IsExtensionMethod || ((object)node.SymbolOpt != null && node.SymbolOpt.RequiresInstanceReceiver))
{
BoundExpression receiver = ((BoundMethodGroup)node.Operand).ReceiverOpt;
// A method group's "implicit this" is only used for instance methods.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ protected virtual int MakeSlot(BoundExpression node)
case BoundKind.PropertyAccess:
if (TryGetReceiverAndMember(node, out BoundExpression receiver, out Symbol member))
{
Debug.Assert((receiver is null) == member.IsStatic);
Debug.Assert((receiver is null) != member.RequiresInstanceReceiver());
return MakeMemberSlot(receiver, member);
}
break;
Expand All @@ -254,7 +254,7 @@ protected virtual int MakeSlot(BoundExpression node)
protected int MakeMemberSlot(BoundExpression receiverOpt, Symbol member)
{
int containingSlot = -1;
if (!member.IsStatic)
if (member.RequiresInstanceReceiver())
{
if (receiverOpt is null)
{
Expand Down
6 changes: 3 additions & 3 deletions src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,7 @@ protected override bool TryGetReceiverAndMember(BoundExpression expr, out BoundE
}
}

Debug.Assert(member?.IsStatic != true);
Debug.Assert(member?.RequiresInstanceReceiver() ?? true);

return (object)member != null &&
(object)receiver != null &&
Expand Down Expand Up @@ -2739,7 +2739,7 @@ private TypeWithState VisitCallReceiver(BoundCall node)

var type = receiverType.Type;
var method = node.Method;
if (!method.IsStatic &&
if (method.RequiresInstanceReceiver &&
type?.IsNullableType() == true &&
method.ContainingType.IsReferenceType)
{
Expand Down Expand Up @@ -5571,7 +5571,7 @@ private void VisitMemberAccess(BoundExpression node, BoundExpression receiverOpt
var receiverType = (receiverOpt != null) ? VisitRvalueWithState(receiverOpt) : default;

SpecialMember? nullableOfTMember = null;
if (!member.IsStatic)
if (member.RequiresInstanceReceiver())
{
member = AsMemberOfType(receiverType.Type, member);
nullableOfTMember = GetNullableOfTMember(member);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ protected override LocalState VisitSwitchStatementDispatch(BoundSwitchStatement
// We may need to recompute the Deconstruct method for a deconstruction if
// the receiver type has changed (e.g. its nested nullability).
var method = e.DeconstructMethod;
int extensionExtra = method.IsStatic ? 1 : 0;
int extensionExtra = method.RequiresInstanceReceiver ? 0 : 1;
for (int i = 0; i < method.ParameterCount - extensionExtra; i++)
{
var parameterType = method.Parameters[i + extensionExtra].TypeWithAnnotations;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public override BoundNode VisitSizeOfOperator(BoundSizeOfOperator node)
public override BoundNode VisitLocalFunctionStatement(BoundLocalFunctionStatement node)
{
var outerLocalFunction = _staticLocalFunction;
if (node.Symbol.IsStaticLocalFunction)
if (node.Symbol.IsStatic)
{
_staticLocalFunction = node.Symbol;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ private BoundExpression VisitCall(BoundCall node)
var method = node.Method;
return ExprFactory(
"Call",
method.IsStatic ? _bound.Null(ExpressionType) : Visit(node.ReceiverOpt),
method.RequiresInstanceReceiver ? Visit(node.ReceiverOpt) : _bound.Null(ExpressionType),
_bound.MethodInfo(method),
Expressions(node.Arguments));
}
Expand Down Expand Up @@ -608,7 +608,7 @@ private BoundExpression VisitConversion(BoundConversion node)
case ConversionKind.MethodGroup:
{
var mg = (BoundMethodGroup)node.Operand;
return DelegateCreation(mg.ReceiverOpt, node.SymbolOpt, node.Type, node.SymbolOpt.IsStatic && !node.IsExtensionMethod);
return DelegateCreation(mg.ReceiverOpt, node.SymbolOpt, node.Type, !node.SymbolOpt.RequiresInstanceReceiver && !node.IsExtensionMethod);
}
case ConversionKind.ExplicitUserDefined:
case ConversionKind.ImplicitUserDefined:
Expand Down Expand Up @@ -665,10 +665,10 @@ private BoundExpression Convert(BoundExpression expr, TypeSymbol type, bool isCh
return ExprFactory(isChecked ? "ConvertChecked" : "Convert", expr, _bound.Typeof(type));
}

private BoundExpression DelegateCreation(BoundExpression receiver, MethodSymbol method, TypeSymbol delegateType, bool staticMember)
private BoundExpression DelegateCreation(BoundExpression receiver, MethodSymbol method, TypeSymbol delegateType, bool requiresInstanceReciever)
{
var nullObject = _bound.Null(_objectType);
receiver = staticMember ? nullObject : receiver.Type.IsReferenceType ? receiver : _bound.Convert(_objectType, receiver);
receiver = requiresInstanceReciever ? nullObject : receiver.Type.IsReferenceType ? receiver : _bound.Convert(_objectType, receiver);

var createDelegate = _bound.WellKnownMethod(WellKnownMember.System_Reflection_MethodInfo__CreateDelegate, isOptional: true);
BoundExpression unquoted;
Expand Down Expand Up @@ -700,7 +700,7 @@ private BoundExpression VisitDelegateCreationExpression(BoundDelegateCreationExp

if ((object)node.MethodOpt != null)
{
bool staticMember = node.MethodOpt.IsStatic && !node.IsExtensionMethod;
bool staticMember = !node.MethodOpt.RequiresInstanceReceiver && !node.IsExtensionMethod;
return DelegateCreation(node.Argument, node.MethodOpt, node.Type, staticMember);
}

Expand Down
Loading