Collection expressions: synthesize single-element list type for IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>#71147
Conversation
|
@cston I'd like a review pass on this before I add tests and check well-known members. The enumerator should probably be a nested type.. is there a sample I can follow to make it so? or it's ok for it to be top-level? |
|
Awesome!! |
|
Thanks @alrz, the changes so far LGTM!
I agree, the enumerator type should probably be a nested type. I don't know if we have an example of a nested synthesized type, but perhaps the following changes are needed:
|
thanks for the heads up. I haven't started checking well-known members yet so it won't. I will sync once that PR goes in. btw, would this interact with the planned yield-like codegen (from #68785)? also I was wondering what would it take to remove |
Most likely yes :)
I would be fine with synthesizing empty singleton types. :) But, frankly, we likely should just use the known Array.Empty singleton for these instead. |
# Conflicts: # src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_CollectionExpression.cs # src/Compilers/CSharp/Portable/Symbols/Synthesized/ReadOnlyListType/SynthesizedReadOnlyListTypeSymbol.cs
I'm assuming there's a reason that both roslyn/runtime have a special type for this. Maybe saving a tiny bit of memory? |
Having one actual object exist and be pointed to by literally millions of locations in memory is good :) |
|
@cston @dotnet/roslyn-compiler for review, thanks. |
|
@dotnet/roslyn-compiler for a second review, thanks. |
1 similar comment
|
@dotnet/roslyn-compiler for a second review, thanks. |
|
@333fred, @RikkiGibson, @dotnet/roslyn-compiler, for a second review, thanks. |
| @@ -308,32 +308,36 @@ SpecialType.System_Collections_Generic_IReadOnlyCollection_T or | |||
| int numberIncludingLastSpread; | |||
There was a problem hiding this comment.
I know you didn't name this variable, but... number of what? We need to rename this for clarity. If you want to do it now, go for it, if not we can do it in a follow up.
There was a problem hiding this comment.
Tried lastSpreadIndex here 57dc299 but that's more than a rename. I'll leave it out of this PR.
# Conflicts: # src/Compilers/CSharp/Test/Emit2/Semantics/CollectionExpressionTests.cs
| var typeArgs = ImmutableArray.Create(elementType); | ||
| var synthesizedType = _factory.ModuleBuilderOpt.EnsureReadOnlyListTypeExists(syntax, hasKnownLength: useKnownLength, _diagnostics.DiagnosticBag).Construct(typeArgs); | ||
| var kind = useKnownLength | ||
| ? numberIncludingLastSpread == 0 && elements.Length == 1 && SynthesizedReadOnlyListTypeSymbol.CanCreateSingleElement(_compilation) |
There was a problem hiding this comment.
CanCreateSingleElement
This runs for every single-element collection expr unlike SynthesizedReadOnlyListTypeSymbol.Create. Not sure if this matters but I think we can detect this in EnsureReadOnlyListTypeExists and downgrade instead of checking each time, although that would only optimize the happy path.
|
Thanks @alrz! |
Contributes to #68785