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

Exclude identifiers in misplaced attributes from identifier map #75100

Merged
merged 2 commits into from
Sep 17, 2024

Conversation

jcouv
Copy link
Member

@jcouv jcouv commented Sep 12, 2024

Fixes #73905

For context:

  • buildIdentifierMapOfBindIdentifierTargets builds a map of identifiers that we expect to bind
  • adjustIdentifierMapIfAny updates the map to record which identifiers we actually bound
  • assertBindIdentifierTargets checks the resulting map (already ignored identifiers in presence of binding errors, but now also skips identifiers in presence of warning for misplaced attributes, which causes attributes not to be bound)
  • those checks are meant to align with logic in SynthesizedPrimaryConstructor.GetCapturedParameters

@jcouv jcouv self-assigned this Sep 12, 2024
@dotnet-issue-labeler dotnet-issue-labeler bot added the untriaged Issues and PRs which have not yet been triaged by a lead label Sep 12, 2024
@jcouv jcouv marked this pull request as ready for review September 13, 2024 04:03
@jcouv jcouv requested a review from a team as a code owner September 13, 2024 04:03
@@ -2028,6 +2028,7 @@ static void addIdentifiers(CSharpSyntaxNode? node, ConcurrentDictionary<Identifi
case GotoStatementSyntax { RawKind: (int)SyntaxKind.GotoStatement }:
case TypeParameterConstraintClauseSyntax:
case AliasQualifiedNameSyntax:
case AttributeListSyntax:
Copy link
Contributor

@AlekseyTs AlekseyTs Sep 13, 2024

Choose a reason for hiding this comment

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

case AttributeListSyntax:

I guess I should have added a comment that logic in this lambda is based on Binder.IdentifierUsedAsValueFinder.CheckIdentifiersInNode.childrenNeedChecking. It can be more permissive (i.e. allow us to dive into more nodes), but should not be more restrictive. Since childrenNeedChecking has the following case:

                        case AttributeListSyntax:
                            // References in attributes, if any, are errors
                            // Skip them
                            return false;

I am fine with adding a similar case here with the same comment/explanation. Given the sated goal "Predict all identifiers in the body that should go through Binder.BindIdentifier method", putting it into the bucket of "uninteresting" nodes is somewhat misleading because it contains identifiers that go through Binder.BindIdentifier.

At the same time, I would prefer an alternative approach to suppressing the assert. The one that will allow assertBindIdentifierTargets to be closer to achieving the stated goal (quoted above).

assertBindIdentifierTargets already disables asserts in presence of errors since there is no guaranty that we bind all the identifiers that are supposed to be bound. The scenarios that we are dealing with are actually error scenarios, we skip binding the attributes, but report a warning instead. That is why assertBindIdentifierTargets fails to disable the check. I suggest to fix this flaw instead. I'll make a specific suggestion at the relevant location.
#Closed

@AlekseyTs
Copy link
Contributor

AlekseyTs commented Sep 13, 2024

                            if (flags == 1)

It looks like adding the following code at the end of body of this if suppresses the assert:

if (id.Ancestors(ascendOutOfTrivia: false).OfType<AttributeListSyntax>().Any() &&
    diagnostics.DiagnosticBag!.AsEnumerable().Any(d => d.Code == (int)ErrorCode.WRN_AttributeLocationOnBadDeclaration))
{
    continue;
}
``` #Closed

---
Refers to: src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs:2112 in a3ad201. [](commit_id = a3ad201c5ad78ae8f1229417d4d44d00688f1658, deletion_comment = False)

@@ -1651,6 +1651,11 @@ void adjustIdentifierMapIfAny(SimpleNameSyntax node, bool invoked)
Binder current = this;
while (current is not (null or InMethodBinder { IdentifierMap: not null }))
{
if (current is ContextualAttributeBinder)
Copy link
Contributor

@AlekseyTs AlekseyTs Sep 13, 2024

Choose a reason for hiding this comment

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

if (current is ContextualAttributeBinder)

If we end up keeping an additional logic here (which wouldn't be necessary with the alternative approach), I would prefer it to be a syntactic check based on id. #Closed

@AlekseyTs
Copy link
Contributor

Done with review pass (commit 1)

@jcouv jcouv changed the title Exclude identifiers in attributes from identifier map Exclude identifiers in misplaced attributes from identifier map Sep 13, 2024
@jcouv
Copy link
Member Author

jcouv commented Sep 13, 2024

@dotnet/roslyn-compiler for second review. Thanks

@jcouv jcouv requested a review from AlekseyTs September 13, 2024 19:45
Copy link
Contributor

@AlekseyTs AlekseyTs left a comment

Choose a reason for hiding this comment

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

LGTM (commit 2)

@AlekseyTs
Copy link
Contributor

While merging, consider adjusting commit's title and comment to align them with the latest revision.

@jcouv
Copy link
Member Author

jcouv commented Sep 13, 2024

While merging, consider adjusting commit's title and comment to align them with the latest revision.

Yup. Already done :-)

@jcouv
Copy link
Member Author

jcouv commented Sep 16, 2024

@dotnet/roslyn-compiler for second review. Thanks

@jcouv jcouv merged commit 149c24c into dotnet:main Sep 17, 2024
24 checks passed
@jcouv jcouv deleted the param-issue branch September 17, 2024 18:34
@dotnet-policy-service dotnet-policy-service bot added this to the Next milestone Sep 17, 2024
@akhera99 akhera99 modified the milestones: Next, 17.12 P3 Sep 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Compilers untriaged Issues and PRs which have not yet been triaged by a lead
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Assert failure in BindMethodBody.assertBindIdentifierTargets() with [param:] attribute on local function
4 participants