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

Handle synthesized delegates without refKinds #58802

Merged
merged 5 commits into from
Jan 13, 2022

Conversation

davidwengier
Copy link
Contributor

Fixes #58782

I made an incorrect assumption when adding support for synthesized delegates.

When originally adding support for sythensized delegates I made (wrong) assumptions that delegates were only synthesized for lambdas where there were ref parameters. Turns out any lambda with more than 16 parameters (incl return) also get synthesized delegates, and my delegate name parsing blew up. This fixes that.
@AlekseyTs
Copy link
Contributor

    internal static bool TryParseSynthesizedDelegateName(string name, out RefKindVector byRefs, out bool returnsVoid, out int generation, out int parameterCount)

I am assuming there is a method that produces the names that this method parses and that both methods should be in sync. Consider adding a doc comment with a reference to that other method and similar comment on that method pointing back.


Refers to: src/Compilers/CSharp/Portable/Symbols/Synthesized/GeneratedNames.cs:378 in 40ffc9e. [](commit_id = 40ffc9e, deletion_comment = False)

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)

@tmat
Copy link
Member

tmat commented Jan 12, 2022

    internal static bool TryParseSynthesizedDelegateName(string name, out RefKindVector byRefs, out bool returnsVoid, out int generation, out int parameterCount)

Consider adding unit test that directly invokes TryParseSynthesizedDelegateName and fully covers all branches of the parsing logic (including malformed strings).

Another simple test could also check roundripping with MakeSynthesizedDelegateName.


Refers to: src/Compilers/CSharp/Portable/Symbols/Synthesized/GeneratedNames.cs:378 in 40ffc9e. [](commit_id = 40ffc9e, deletion_comment = False)

@RikkiGibson RikkiGibson self-assigned this Jan 12, 2022
@davidwengier
Copy link
Contributor Author

Another simple test could also check roundripping with MakeSynthesizedDelegateName.

There is an Assert at the end of the method that does that.

Tests for the early exits is a good idea though.

@davidwengier
Copy link
Contributor Author

davidwengier commented Jan 12, 2022

Added documentation and new tests, which don't look very exciting, but they cover it all:
image

The part not covered is currently impossible to hit, as it would need the DelegateNamePrefixLength value to be incorrect (less than ActionDelegateNamePrefix or FuncDelegateNamePrefix) but I don't see any harm in leaving the condition in the code.

[InlineData("<>F`1", false, 0, 0)]
[InlineData("<>F`6", false, 0, 5)]
[InlineData("<>F`19", false, 0, 18)]
[InlineData("<>F#3`19", false, 3, 18)]
Copy link
Member

@cston cston Jan 12, 2022

Choose a reason for hiding this comment

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

Consider testing

  • "<>F{01}#3`1"
  • "<>F{0,1}`1"
  • "<>A{0,}"
  • "<>A{,1}"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just to confirm, you're saying these should be successfully parsed? Currently two of them fail to because RefKindVector.TryParse doesn't like them, and the other two fail on roundtripping because RefKindVector.TryParse and RefKindVector.ToRefKindString aren't really round trippable (Parse will parse something that ToRefKindString will assert on).

I'm happy to fix all of that, just wanted to confirm, and confirm its not overstepping this PR.

[InlineData("<>A00}")]
[InlineData("<>ABCDEF")]
[InlineData("<>A{Z}")]
[InlineData("<>A#F")]
Copy link
Member

@cston cston Jan 12, 2022

Choose a reason for hiding this comment

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

Consider testing

  • "<>A{}"
  • "<>A{,}"
  • "<>A#"

// We need to strip arity in order to validate round-tripping
name = MetadataHelpers.InferTypeArityAndUnmangleMetadataName(name, out _);
Assert.Equal(name, GeneratedNames.MakeSynthesizedDelegateName(actualByRefs, actualReturnsVoid, actualGeneration));
}
Copy link
Member

Choose a reason for hiding this comment

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

Duplicate blank lines above.

Copy link
Member

@tmat tmat left a comment

Choose a reason for hiding this comment

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

:shipit:

@davidwengier davidwengier enabled auto-merge (squash) January 13, 2022 01:05
@davidwengier
Copy link
Contributor Author

Thanks all!

@davidwengier davidwengier merged commit fa9926d into dotnet:main Jan 13, 2022
@ghost ghost added this to the Next milestone Jan 13, 2022
@davidwengier davidwengier deleted the EnCMoreSynthesizedDelegates branch January 13, 2022 05:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[EnC] Edit and continue fails in method with delegate invocation with > 15 parameters
5 participants