-
Notifications
You must be signed in to change notification settings - Fork 4k
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
Implement remaining span conversions #74420
Implement remaining span conversions #74420
Conversation
f7577ec
to
d751f5f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done review pass
src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionsBase.cs
Outdated
Show resolved
Hide resolved
{ | ||
// (4,44): error CS0030: Cannot convert type 'System.ReadOnlySpan<int>' to 'System.Span<int>' | ||
// Span<int> M(ReadOnlySpan<int> arg) => (Span<int>)arg; | ||
Diagnostic(ErrorCode.ERR_NoExplicitConv, "(Span<int>)arg").WithArguments("System.ReadOnlySpan<int>", "System.Span<int>").WithLocation(4, 44) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would expect this to be legal. #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why? There is no implicit nor explicit conversion from ReadOnlySpan to Span (the opposite conversion exists). There is an explicit span conversion only from array to (ReadOnly)Span. We could propose other explicit conversions but I'm not sure how we would emit them anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because the type defines a UDC that permits it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I missed that. Then you're right that looks a bit unexpected, let me check what's happening.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, this UDC is ignored - per the speclet:
User-defined conversions are not considered when converting between
- any single-dimensional
array_type
andSystem.Span<T>
/System.ReadOnlySpan<T>
,- any combination of
System.Span<T>
/System.ReadOnlySpan<T>
,string
andSystem.ReadOnlySpan<char>
.
This case is the second bullet point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does not care about converting from
ReadOnlySpan
toSpan
.
The speclet cares about that conversion actually - because it's the opposite conversion of the implicit Span->ReadOnlySpan, and the standard says that for any implicit conversion the opposite explicit conversion exists. So the speclet needs to say that the ROS->Span standard explicit conversion doesn't exist.
The only things the speclet should talk about are the conversions that it actually cares about.
So you are suggesting we only disallow UDCs for the conversions the compiler can emit?
My intent was that the compiler handles all conversions between Spans (otherwise it's inconsistent). I think @cston suggested that as well for example in #73577 (comment).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The spec should certainly say that no ROS->Span standard explicit conversion exists, but that isn't what we have here. We have a UDC. We shouldn't be disallowing this, as the feature doesn't care about it. It of course can't fall in the bucket of a standard implicit conversion; it can't contribute to the things that only "standard" conversions can. But it can absolutely still exist and be used, and be called by user code as any UDC can.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, works for me. Updating the speclet in dotnet/csharplang#8312 (the second commit is relevant to this discussion).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why the speclet says that. The only things the speclet should talk about are the conversions that it actually cares about. It does not care about converting from
ReadOnlySpan
toSpan
.
My expectation is that if some conversions between spans and arrays, spans, and strings are handled directly in the compiler, then all such conversions should be handled in the compiler, and the compiler should not fallback to user-defined conversions between these types. Was this covered at LDM?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was this covered at LDM?
It wasn't, adding an open question in dotnet/csharplang#8312.
@cston for a second review, thanks |
src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionsBase.cs
Outdated
Show resolved
Hide resolved
Are we testing cases where there is not an implicit reference conversion between element types?
|
Consider testing:
|
Consider testing:
|
I'm surprised we allow user-defined conversions between spans and arrays, spans, or strings. #Resolved Refers to: src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs:2320 in d9e4b71. [](commit_id = d9e4b71, deletion_comment = False) |
Should this be ... ?
|
Is this case different than Refers to: src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs:3143 in d9e4b71. [](commit_id = d9e4b71, deletion_comment = False) |
Is this case different than Refers to: src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs:3172 in d9e4b71. [](commit_id = d9e4b71, deletion_comment = False) |
I'm surprised we allow explicit user-defined conversions between spans and arrays, spans, or strings. #Resolved Refers to: src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs:3684 in d9e4b71. [](commit_id = d9e4b71, deletion_comment = False) |
We didn't, but Fred said we should. See #74420 (comment). Specifically we now only disallow UDCs where span conversions exist - e.g., in this example, there is no span conversion between In reply to: 2259370393 Refers to: src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs:2320 in d9e4b71. [](commit_id = d9e4b71, deletion_comment = False) |
Looks the same, I will remove this one, thanks. In reply to: 2259384495 Refers to: src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs:3143 in d9e4b71. [](commit_id = d9e4b71, deletion_comment = False) |
Yes, this one tests In reply to: 2259384850 Refers to: src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs:3172 in d9e4b71. [](commit_id = d9e4b71, deletion_comment = False) |
It was modeled on the previous test (only with a Span instead of an array). But I will add the test you are suggesting. In reply to: 2259378657 Refers to: src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs:2754 in d9e4b71. [](commit_id = d9e4b71, deletion_comment = False) |
Yes, the tests have suffix In reply to: 2259350562 Refers to: src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs:487 in d9e4b71. [](commit_id = d9e4b71, deletion_comment = False) |
These conversions are already tested in In reply to: 2259368438 Refers to: src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs:2305 in d9e4b71. [](commit_id = d9e4b71, deletion_comment = False) |
The I agree this is confusing, and I thought about removing this In reply to: 2259344500 Refers to: src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs:327 in d9e4b71. [](commit_id = d9e4b71, deletion_comment = False) |
Added a comment here. We should discuss at LDM whether to allow user-defined conversions, if not already discussed. In reply to: 2262345108 Refers to: src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs:2320 in d9e4b71. [](commit_id = d9e4b71, deletion_comment = False) |
@333fred for another look, thanks |
Test plan: #73445