-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Analyzer proposal: treat calls to ROS<char> op_Equality as warning #54794
Comments
Tagging subscribers to this area: @dotnet/area-system-runtime Issue DetailsDescriptionThere have been a few issues filed (#10151, #54793) where developers are confused as to why two We should consider introducing an analyzer that detects ExamplesReadOnlySpan<char> span1;
ReadOnlySpan<char> span2;
// produces warnings
if (span1 == span2) { /* ... */ }
if (span1 != span2) { /* ... */ }
// suggested fixer replacements
if (span1.SequenceEqual(span2)) { /* ... */ }
if (!span1.SequenceEqual(span2)) { /* ... */ }
ReadOnlySpan<T> span3;
ReadOnlySpan<T> span4;
// DOES NOT produce warning
if (span3 == span4) { /* ... */ } DiscussionThis analyzer assumes that the majority use case of Additionally, this analyzer & fixer would only capture Open questionsShould the analyzer also trap calls to string str = GetString();
ReadOnlySpan<char> span = str;
int idx1 = str.IndexOf("hello"); // linguistic, current-culture
int idx2 = span.IndexOf("hello"); // ordinal Related to this last point: #43956
|
Thanks, this was very confusing. Is there a reason why ReadOnlySpan == string is allowed? It sounds like this shouldn't be used so I wonder why this is possible. Maybe the analyze should treat this as error instead of a warning (it could be fixed by calling AsSpan method on the string). |
@Symbai Since you repeated your question, I'll repeat my answer:
|
/cc @tarekgh for his thoughts on globalization (see Open questions at the bottom of the issue description). |
I am not seeing any reason to have the analyzer trap such calls. is there a concern that users can do something wrong here? |
@tarekgh This issue was primarily that equality ( |
@GrabYourPitchforks For such specific cases, the analyzer should trap the IndexOf calls which take a string and not passing the StringComparison option. but for the methods that takes ROS, the default behavior is the desired one and better avoid flagging these calls. Of course, if we find any usage in the future suggest adding the analyzer rule, we can do it by then. |
This probably extends to |
If you warn on the equality operator regardless of T, I agree it would make sense to extend this to |
This analyzer should not trigger a warning on comparisons against 'default'. |
@GrabYourPitchforks the proposal sounds reasonable. Do you want to mark it as ready for review? Pending adding to the main description:
|
Ping @tannergooding for the ask above. And @GrabYourPitchforks let me know if this is ready for review. |
I don't have a strong preference on ArraySegment and it can be covered in API review as a side note/consideration. |
Similarly, I don't have a strong preference on |
It seems we should have a method: namespace System;
public static class MemoryExtensions
{
public static bool ReferenceEqual<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other);
public static bool ReferenceEqual<T>(this Span<T> span, ReadOnlySpan<T> other);
} @GrabYourPitchforks please file an issue for the API. |
This comment was marked as resolved.
This comment was marked as resolved.
Why does it need IEquatable constraints at all? |
It doesn't. It's a copy paste bug because I started with |
Removing the |
Estimates:
|
@terrajobst @tannergooding The argument that the analyzer should work for any T because people coming from other languages might expect it to do SequenceEqual as opposed to reference equality, applies not only to ReadOnlySpan, but for arrays and all other collections as well. By that logic, the analyzer should warn for all collection types because they all default to reference equality. Span shouldn't be special in that. I don't think we should do this unless we're sure that using I'm really not keen on the idea of making Span special as the only collection where it's discouraged to use |
Description
There have been a few issues filed (#10151, #54793) where developers are confused as to why two
ROS<char>
sequences can't be compared for content equality usingoperator ==
, like normal string instances can be.We should consider introducing an analyzer that detects
operator ==
andoperator !=
calls onSpan<char>
andReadOnlySpan<char>
specifically and introduces a warning, also offering to fix the call sites by rewriting this in terms ofSequenceEqual
.Examples
Discussion
This analyzer assumes that the majority use case of
ROS<char>
is as a substitute for string segments, so these callers would want API behaviors that match the behaviors they're used to on string. However, we shouldn't assume that all callers are treatingSpan<char>
in this fashion; as some may really want to treat these as slices into an arbitrary data buffer and maintain the existing pointer / length equality comparisons. This may affect whether a fixer is enabled by default.Additionally, this analyzer & fixer would only capture
ROS<char>
andSpan<char>
, not any other T. If the caller is using a generic T, they're almost certainly intending this to be a data buffer slice, not stringy data.Open questions
Should the analyzer also trap calls to
MemoryExtensions.IndexOf<char>(ReadOnlySpan<char>, ReadOnlySpan<char>)
and related APIs? These have different behaviors than their corresponding string methods, as shown in the below examples.Related to this last point: #43956
The text was updated successfully, but these errors were encountered: