Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ internal MethodInfo ReplaceWithExtensionImplementation(out bool wasError)

wasError = (Method is not null && method is null) || (SetMethod is not null && setMethod is null);

// Tracked by https://github.com/dotnet/roslyn/issues/76130 : Test with indexers (ie. "method") and in compound assignment (ie. "setMethod")
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 I added a note to indexers follow-up issue. @AlekseyTs, I assume you're already covering this in your current ref analysis work for operators

Copy link
Contributor

@AlekseyTs AlekseyTs Jun 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and in compound assignment (ie. "setMethod")

Is the "and in compound assignment (ie. "setMethod")" part covered or tracked somewhere? #Closed

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the follow-up note was moved to #78829

Copy link
Contributor

@AlekseyTs AlekseyTs Jun 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the follow-up note was moved to ...

The issue looks indexer specific, but the mentioned scenario is not.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the operator scenario, I left a comment to you to check that you're tracking it as part of operators: #78971 (comment)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the operator scenario ...

I do not think this comment is about an operator scenario, but about a property scenario.

// Tracked by https://github.com/dotnet/roslyn/issues/76130 : Test in compound assignment (ie. "setMethod")
return new MethodInfo(symbol, method, setMethod);

static MethodSymbol? replace(MethodSymbol? method)
Expand Down
10 changes: 5 additions & 5 deletions src/Compilers/CSharp/Portable/Binder/Binder_Conversions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1467,7 +1467,7 @@ static ImmutableArray<MethodSymbol> filterOutBadGenericMethods(

if (!typeParameters.IsEmpty)
{
if (resolution.IsExtensionMethodGroup) // Tracked by https://github.com/dotnet/roslyn/issues/76130 : we need to handle new extension methods
if (resolution.IsExtensionMethodGroup) // Tracked by https://github.com/dotnet/roslyn/issues/78960 : we need to handle new extension methods
{
// We need to validate an ability to infer type arguments as well as check conversion to 'this' parameter.
// Overload resolution doesn't check the conversion when 'this' type refers to a type parameter
Expand Down Expand Up @@ -1518,7 +1518,7 @@ static ImmutableArray<MethodSymbol> filterOutBadGenericMethods(
parameterTypes,
parameterRefKinds,
ImmutableArray.Create<BoundExpression>(methodGroup.ReceiverOpt, new BoundValuePlaceholder(syntax, secondArgumentType) { WasCompilerGenerated = true }),
ref useSiteInfo); // Tracked by https://github.com/dotnet/roslyn/issues/76130 : we may need to override ordinals here
ref useSiteInfo); // Tracked by https://github.com/dotnet/roslyn/issues/78960 : we may need to override ordinals here

if (!inferenceResult.Success)
{
Expand Down Expand Up @@ -1601,7 +1601,7 @@ static bool bindInvocationExpressionContinued(
var methodResult = result.ValidResult;
var method = methodResult.Member;

// Tracked by https://github.com/dotnet/roslyn/issues/76130: It looks like we added a bunch of code in BindInvocationExpressionContinued at this position
// Tracked by https://github.com/dotnet/roslyn/issues/78960: It looks like we added a bunch of code in BindInvocationExpressionContinued at this position
// that specifically deals with new extension methods. It adjusts analyzedArguments, etc.
// It is very likely we need to do the same here.

Expand Down Expand Up @@ -1663,7 +1663,7 @@ internal static BoundExpression GetUnderlyingCollectionExpressionElement(BoundCo
// Add methods. This case can be hit for spreads and non-spread elements.
Debug.Assert(call.HasErrors);
Debug.Assert(call.Method.Name == "Add");
return call.Arguments[call.InvokedAsExtensionMethod ? 1 : 0]; // Tracked by https://github.com/dotnet/roslyn/issues/76130: Add test coverage for new extensions
return call.Arguments[call.InvokedAsExtensionMethod ? 1 : 0]; // Tracked by https://github.com/dotnet/roslyn/issues/78960: Add test coverage for new extensions
case BoundBadExpression badExpression:
Debug.Assert(false); // Add test if we hit this assert.
return badExpression;
Expand Down Expand Up @@ -1712,7 +1712,7 @@ internal bool TryGetCollectionIterationType(SyntaxNode syntax, TypeSymbol collec
out iterationType,
builder: out var builder);
// Collection expression target types require instance method GetEnumerator.
if (result && builder.ViaExtensionMethod) // Tracked by https://github.com/dotnet/roslyn/issues/76130: Add test coverage for new extensions
if (result && builder.ViaExtensionMethod) // Tracked by https://github.com/dotnet/roslyn/issues/78960: Add test coverage for new extensions
{
iterationType = default;
return false;
Expand Down
2 changes: 1 addition & 1 deletion src/Compilers/CSharp/Portable/Binder/Binder_Crefs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ private ImmutableArray<Symbol> BindIndexerMemberCref(IndexerMemberCrefSyntax syn

private ImmutableArray<Symbol> BindExtensionMemberCref(ExtensionMemberCrefSyntax syntax, NamespaceOrTypeSymbol? containerOpt, out Symbol? ambiguityWinner, BindingDiagnosticBag diagnostics)
{
// Tracked by https://github.com/dotnet/roslyn/issues/76130 : handle extension operators
// Tracked by https://github.com/dotnet/roslyn/issues/78967 : cref, handle extension operators
CheckFeatureAvailability(syntax, MessageID.IDS_FeatureExtensions, diagnostics);

if (containerOpt is not NamedTypeSymbol namedContainer)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8045,7 +8045,7 @@ private BoundExpression GetExtensionMemberAccess(SyntaxNode syntax, BoundExpress
return BindPropertyAccess(syntax, receiver, propertySymbol, diagnostics, LookupResultKind.Viable, hasErrors: false);

case ExtendedErrorTypeSymbol errorTypeSymbol:
// Tracked by https://github.com/dotnet/roslyn/issues/76130 : we should likely reduce (ie. do type inference and substitute) the candidates (like ToBadExpression)
// Tracked by https://github.com/dotnet/roslyn/issues/78957 : public API, we should likely reduce (ie. do type inference and substitute) the candidates (like ToBadExpression)
return new BoundBadExpression(syntax, LookupResultKind.Viable, errorTypeSymbol.CandidateSymbols!, [receiver], CreateErrorType());

default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ private BoundInterpolatedString BindUnconvertedInterpolatedExpressionToFactory(
SyntaxNode syntax = unconvertedSource.Syntax;
ImmutableArray<BoundExpression> expressions = makeInterpolatedStringFactoryArguments(syntax, parts, diagnostics);

BoundExpression construction = MakeInvocationExpression( // Tracked by https://github.com/dotnet/roslyn/issues/76130 : test this scenario with a delegate-returning property (should be blocked by virtue of allowFieldsAndProperties: false)
BoundExpression construction = MakeInvocationExpression( // Tracked by https://github.com/dotnet/roslyn/issues/78965 : interpolated string, test this scenario with a delegate-returning property (should be blocked by virtue of allowFieldsAndProperties: false)
syntax,
new BoundTypeExpression(syntax, null, factoryType) { WasCompilerGenerated = true },
factoryMethod,
Expand Down
2 changes: 1 addition & 1 deletion src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3565,7 +3565,7 @@ private void EmitParameterIdExpression(BoundParameterId node)

if (node.HoistedField is null)
{
_builder.EmitIntConstant(node.Parameter.Ordinal); // Tracked by https://github.com/dotnet/roslyn/issues/76130 : Follow up
_builder.EmitIntConstant(node.Parameter.Ordinal); // Tracked by https://github.com/dotnet/roslyn/issues/78963 : Follow up
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3371,7 +3371,7 @@ private OneOrMany<Symbol> GetSemanticSymbols(
case BoundKind.PropertyGroup:
symbols = GetPropertyGroupSemanticSymbols((BoundPropertyGroup)boundNode, boundNodeForSyntacticParent, binderOpt, out resultKind, out memberGroup);
break;
// Tracked by https://github.com/dotnet/roslyn/issues/76130 : handle BoundPropertyAccess (which now may have a member group)
// Tracked by https://github.com/dotnet/roslyn/issues/78957 : public API, consider handling BoundPropertyAccess (which now may have a member group)

case BoundKind.BadExpression:
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ method.OriginalDefinition is ErrorMethodSymbol ||
public override BoundNode? VisitMethodDefIndex(BoundMethodDefIndex node)
{
MethodSymbol method = node.Method;
Debug.Assert(method.IsDefinition); // Tracked by https://github.com/dotnet/roslyn/issues/76130 : From the code coverage and other instrumentations perspective, should we remap the index to the implementation symbol?
Debug.Assert(method.IsDefinition); // Tracked by https://github.com/dotnet/roslyn/issues/78962 : From the code coverage and other instrumentations perspective, should we remap the index to the implementation symbol?
TypeSymbol? type = this.VisitType(node.Type);
return node.Update(method, type);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ private void AddNameAndTypeArgumentsOrParameters(INamedTypeSymbol symbol)
{
if (Format.CompilerInternalOptions.HasFlag(SymbolDisplayCompilerInternalOptions.UseMetadataMemberNames))
{
var extensionIdentifier = underlyingTypeSymbol!.ExtensionName; // Tracked by https://github.com/dotnet/roslyn/issues/76130 : use public API once it's available
var extensionIdentifier = underlyingTypeSymbol!.ExtensionName; // Tracked by https://github.com/dotnet/roslyn/issues/78957 : public API, use public API once it's available
Builder.Add(CreatePart(SymbolDisplayPartKind.ClassName, symbol, extensionIdentifier));
}
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ protected RewrittenMethodSymbol(MethodSymbol originalMethod, TypeMap typeMap, Im
Debug.Assert(originalMethod.ExplicitInterfaceImplementations.IsEmpty);

_originalMethod = originalMethod;
// Tracked by https://github.com/dotnet/roslyn/issues/76130 : Are we creating type parameters with the right emit behavior? Attributes, etc.
// Tracked by https://github.com/dotnet/roslyn/issues/78963 : Are we creating type parameters with the right emit behavior? Attributes, etc.
_typeMap = typeMap.WithAlphaRename(typeParametersToAlphaRename, this, out _typeParameters);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ public RewrittenParameterSymbol(ParameterSymbol originalParameter) :

internal sealed override int CallerArgumentExpressionParameterIndex => _underlyingParameter.CallerArgumentExpressionParameterIndex;

internal sealed override ImmutableArray<int> InterpolatedStringHandlerArgumentIndexes => throw ExceptionUtilities.Unreachable(); // Tracked by https://github.com/dotnet/roslyn/issues/76130 : Follow up
internal sealed override ImmutableArray<int> InterpolatedStringHandlerArgumentIndexes => throw ExceptionUtilities.Unreachable(); // Tracked by https://github.com/dotnet/roslyn/issues/78965 : interpolated string, Follow up

internal sealed override bool HasInterpolatedStringHandlerArgumentError => throw ExceptionUtilities.Unreachable(); // Tracked by https://github.com/dotnet/roslyn/issues/76130 : Follow up
internal sealed override bool HasInterpolatedStringHandlerArgumentError => throw ExceptionUtilities.Unreachable(); // Tracked by https://github.com/dotnet/roslyn/issues/78965 : interpolated string, Follow up
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public SourceExtensionImplementationMethodSymbol(MethodSymbol sourceMethod)
Debug.Assert(!sourceMethod.IsExtern);
Debug.Assert(!sourceMethod.IsExternal);

// Tracked by https://github.com/dotnet/roslyn/issues/76130 : Are we creating type parameters with the right emit behavior? Attributes, etc.
// Tracked by https://github.com/dotnet/roslyn/issues/78963 : Are we creating type parameters with the right emit behavior? Attributes, etc.
// Also, they should be IsImplicitlyDeclared
}

Expand Down Expand Up @@ -126,7 +126,7 @@ protected override ImmutableArray<ParameterSymbol> MakeParameters()

if (!_originalMethod.IsStatic)
{
// Tracked by https://github.com/dotnet/roslyn/issues/76130 : Need to confirm if this rewrite going to break LocalStateTracingInstrumenter
// Tracked by https://github.com/dotnet/roslyn/issues/78962 : Need to confirm if this rewrite going to break LocalStateTracingInstrumenter
// Specifically BoundParameterId, etc.
parameters.Add(new ExtensionMetadataMethodParameterSymbol(this, ((SourceNamedTypeSymbol)_originalMethod.ContainingType).ExtensionParameter!));
}
Expand Down
2 changes: 1 addition & 1 deletion src/Compilers/CSharp/Portable/Symbols/NamedTypeSymbol.cs
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ internal void DoGetExtensionMethods(ArrayBuilder<MethodSymbol> methods, string n
{
var thisParam = method.Parameters.First();

// Tracked by https://github.com/dotnet/roslyn/issues/76130 : we should use similar logic when looking up new extension members
// Tracked by https://github.com/dotnet/roslyn/issues/78827 : MQ, we should use similar logic when looking up new extension members
if ((thisParam.RefKind == RefKind.Ref && !thisParam.Type.IsValueType) ||
(thisParam.RefKind is RefKind.In or RefKind.RefReadOnlyParameter && thisParam.Type.TypeKind != TypeKind.Struct))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ static bool isPossibleIndexerNameAttribute(AttributeSyntax node, Binder? rootBin

static bool isPossibleIndexerNameAttributeInExtension(AttributeSyntax node, Binder? rootBinderOpt)
{
// Tracked by https://github.com/dotnet/roslyn/issues/76130 : Temporarily limit binding to a string literal argument in order to avoid a binding cycle.
// Tracked by https://github.com/dotnet/roslyn/issues/78829 : extension indexers, Temporarily limit binding to a string literal argument in order to avoid a binding cycle.
if (node.ArgumentList?.Arguments is not [{ NameColon: null, NameEquals: null, Expression: LiteralExpressionSyntax { RawKind: (int)SyntaxKind.StringLiteralExpression } }])
{
return false;
Expand Down
2 changes: 1 addition & 1 deletion src/Compilers/CSharp/Portable/Syntax/Syntax.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4359,7 +4359,7 @@
</Field>
<Field Name="Type" Type="TypeSyntax" Optional="true" Override="true"/>
<Field Name="Identifier" Type="SyntaxToken" Optional="true">
<!-- Tracked by https://github.com/dotnet/roslyn/issues/76130 : enforce that a ParameterSyntax cannot be created with both Type and Identifier missing -->
<!-- Tracked by https://github.com/dotnet/roslyn/issues/78961 : enforce that a ParameterSyntax cannot be created with both Type and Identifier missing -->
<PropertyComment>
<summary>Gets the identifier.</summary>
</PropertyComment>
Expand Down
2 changes: 1 addition & 1 deletion src/Compilers/CSharp/Portable/Syntax/SyntaxKindFacts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -853,7 +853,7 @@ public static SyntaxKind GetBaseTypeDeclarationKind(SyntaxKind kind)
return kind == SyntaxKind.EnumKeyword ? SyntaxKind.EnumDeclaration : GetTypeDeclarationKind(kind);
}

// Tracked by https://github.com/dotnet/roslyn/issues/76130 : decide what we want for extension declaration
// Tracked by https://github.com/dotnet/roslyn/issues/78957 : public API, decide what we want for extension declaration
public static SyntaxKind GetTypeDeclarationKind(SyntaxKind kind)
{
switch (kind)
Expand Down
Loading