-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Annotate ReferenceManager #42348
Annotate ReferenceManager #42348
Conversation
@@ -424,19 +424,20 @@ private bool CreateAndSetSourceAssemblyFullBind(CSharpCompilation compilation) | |||
|
|||
for (int i = 1; i < bindingResult.Length; i++) | |||
{ | |||
if ((object)bindingResult[i].AssemblySymbol == null) | |||
ref BoundInputAssembly bound = ref bindingResult[i]; |
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 lack of member tracking in arrays was particularly problematic for this change. Then again this code is essentially paassing around large arrays of mutable struct
values. It's the worst possible case for nullability. This doesn't make me want to push for array index tracking (that's really expensive) but it does make me think that if we were doing this again we would've chosen a different approach. Possibly wrapping this array in a simple struct
wrapper that could've handled many of these assertions.
@@ -567,36 +568,41 @@ private bool CreateAndSetSourceAssemblyFullBind(CSharpCompilation compilation) | |||
|
|||
foreach (int i in newSymbols) | |||
{ | |||
ref BoundInputAssembly currentBindingResult = ref bindingResult[i]; |
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.
This is another theme in this PR: stop passing around an array an index. The lack of array index state tracking makes this hard to manage. Instead just pass around a ref
to the array element. This also has the benefit of reducing the amount of times we dereference the array at runtime.
src/Compilers/Core/Portable/ReferenceManager/CommonReferenceManager.Resolution.cs
Outdated
Show resolved
Hide resolved
@dotnet/roslyn-compiler PTAL |
src/Compilers/Core/Portable/ReferenceManager/CommonReferenceManager.Resolution.cs
Outdated
Show resolved
Hide resolved
{ | ||
private readonly AssemblyIdentity _referenceIdentity; | ||
private readonly AssemblyIdentity? _referenceIdentity; |
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.
Both constructors use non-nullable referenceIdentity
. I assume this field is marked as nullable because one might do default(AssemblyReferenceBinding)
. Is that the reason?
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.
Yes. The runtime nullable annotation guide favors treating reference fields in structs as nullable since the use case default(T)
must be considered. There are some exceptions considered but my reading is that it should be the rare case.
|
||
private string GetDebuggerDisplay() | ||
private string? GetDebuggerDisplay() |
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.
Just curious, how does the debugger behave when the method given to DebuggerDisplay
returns null
?
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.
For the way it's defined on this type, using the [DebuggerDisplay]
attribute, it will display simply null
.
Can we remove these (also below)? Refers to: src/Compilers/Core/Portable/ReferenceManager/CommonReferenceManager.Binding.cs:1017 in dbb8542. [](commit_id = dbb8542e5c9269794800d7dc0104515009801903, deletion_comment = False) |
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 with review pass (iteration 4)
@jaredpar This PR probably needs updating (possibly merging) to resolve build issues. |
@jcouv thanks, should be fixed now. |
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.
LGTM Thanks (iteration 8)
@dotnet/roslyn-compiler can I please get a second review? PR is two weeks old. |
@@ -200,7 +201,7 @@ public ReferencedAssemblyIdentity(AssemblyIdentity identity, MetadataReference r | |||
TCompilation compilation, | |||
[Out] Dictionary<string, List<ReferencedAssemblyIdentity>> assemblyReferencesBySimpleName, | |||
out ImmutableArray<MetadataReference> references, | |||
out IDictionary<(string, string), MetadataReference> boundReferenceDirectiveMap, | |||
[NotNull] out IDictionary<(string, string), MetadataReference>? boundReferenceDirectiveMap, |
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.
what does it do to put 'NotNull' on an 'out' parameter of a reference type?
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's like [NotNullWhen]
except that the "When" portion is always true
. Basically this method will unconditionally assign a non-null value to the parameter.
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.
What I was trying to ask is: why can't this parameter be written as out IDictionary<(string, string), MetadataReference> boundReferenceDirectiveMap
, instead of the way it is now? i.e. deleting the NotNullAttribute as well as the top-level nullable annotation.
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.
Removing the ?
annotation though would mean that I'd have to provide a non-null value at the call site correct? That would break the existing code.
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 think this is the scenario you are referring to. This doesn't produce a warning because we know the variable we pass using 'out' will only be written to.
public void M1(string? s1)
{
M2(out s1); // no warning
s1.ToString();
}
public void M2(out string s2)
{
s2 = "a";
}
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 okay. Yeah then [NonNull]
can be removed
No description provided.