The compiler is updating its handling of maybe-null values, and in doing so we're getting a bunch of new warnings. We've not yet ingested the new compiler, but this proactively addresses the warnings for when we do.
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Runtime.Serialization;
namespace System.Collections.Generic
internal sealed class TreeSubSet : SortedSet<T>, ISerializable, IDeserializationCallback
{
private readonly SortedSet<T> _underlying;
- private readonly T _min, _max;
+ [MaybeNull, AllowNull]
+ private readonly T _min;
+ [MaybeNull, AllowNull]
+ private readonly T _max;
// keeps track of whether the count variable is up to date
// up to date -> _countVersion = _underlying.version
// not up to date -> _countVersion < _underlying.version
}
#endif
- public TreeSubSet(SortedSet<T> Underlying, T Min, T Max, bool lowerBoundActive, bool upperBoundActive)
+ public TreeSubSet(SortedSet<T> Underlying, [AllowNull] T Min, [AllowNull] T Max, bool lowerBoundActive, bool upperBoundActive)
: base(Underlying.Comparer)
{
_underlying = Underlying;
return -1;
}
- internal Node? FindRange(T from, T to) => FindRange(from, to, lowerBoundActive: true, upperBoundActive: true);
+ internal Node? FindRange([AllowNull] T from, [AllowNull] T to) => FindRange(from, to, lowerBoundActive: true, upperBoundActive: true);
- internal Node? FindRange(T from, T to, bool lowerBoundActive, bool upperBoundActive)
+ internal Node? FindRange([AllowNull] T from, [AllowNull] T to, bool lowerBoundActive, bool upperBoundActive)
{
Node? current = root;
while (current != null)
}
}
- public virtual SortedSet<T> GetViewBetween(T lowerValue, T upperValue)
+ public virtual SortedSet<T> GetViewBetween([AllowNull] T lowerValue, [AllowNull] T upperValue)
{
if (Comparer.Compare(lowerValue, upperValue) > 0)
{
Func<Pair<bool, T>, T> resultSelector = MakeResultSelectorFunction();
AssociativeAggregationOperator<T, Pair<bool, T>, T> aggregation =
- new AssociativeAggregationOperator<T, Pair<bool, T>, T>(source, new Pair<bool, T>(false, default), null,
+ new AssociativeAggregationOperator<T, Pair<bool, T>, T>(source, new Pair<bool, T>(false, default!), null,
true, intermediateReduce, finalReduce, resultSelector, default(T)! != null, QueryAggregationOptions.AssociativeCommutative);
return aggregation.Aggregate();
if (_source.MoveNext(ref current!, ref keyUnused))
{
currentElement = new Pair<TInputOutput, THashKey>(
- current, _keySelector == null ? default : _keySelector(current));
+ current, _keySelector == null ? default! : _keySelector(current));
return true;
}
return false;
if (_source.MoveNext(ref current!, ref currentKey))
{
currentElement = new Pair<TInputOutput, THashKey>(
- current, _keySelector == null ? default : _keySelector(current));
+ current, _keySelector == null ? default! : _keySelector(current));
return true;
}
internal struct ConcatKey<TLeftKey, TRightKey>
{
+ [MaybeNull, AllowNull]
private readonly TLeftKey _leftKey;
+ [MaybeNull, AllowNull]
private readonly TRightKey _rightKey;
private readonly bool _isLeft;
return false;
}
- protected abstract bool MoveNextCore(ref TIntermediate currentElement);
+ protected abstract bool MoveNextCore([MaybeNullWhen(false), AllowNull] ref TIntermediate currentElement);
}
}
// Check whether value is in set
internal bool TryGetValue(TKey key, [MaybeNullWhen(false), AllowNull] ref TValue value)
{
- return Find(key, false, false, ref value);
+ return Find(key, false, false, ref value!);
}
internal TValue this[TKey key]
comparer.Equals(key1, key2));
}
- private bool Find(TKey key, bool add, bool set, ref TValue value)
+ private bool Find(TKey key, bool add, bool set, [MaybeNullWhen(false)] ref TValue value)
{
int hashCode = GetKeyHashCode(key);
// A simple constructor that initializes the first/second fields.
//
- public Pair(T first, [MaybeNull, AllowNull] U second)
+ public Pair(T first, U second)
{
_first = first;
_second = second;
TSource element = partition.TryGetElementAt(index, out bool found);
if (found)
{
- return element;
+ return element!;
}
}
else
ThrowHelper.ThrowNoElementsException();
}
- return first;
+ return first!;
}
public static TSource First<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
ThrowHelper.ThrowNoMatchException();
}
- return first;
+ return first!;
}
[return: MaybeNull]
using System.Collections;
using System.Collections.Generic;
-using System.Diagnostics.CodeAnalysis;
namespace System.Linq
{
{
private readonly int _threadId;
internal int _state;
- [MaybeNull, AllowNull]
- internal TSource _current = default; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/37138
+ internal TSource _current = default!;
/// <summary>
/// Initializes a new instance of the <see cref="Iterator{TSource}"/> class.
/// </remarks>
public virtual void Dispose()
{
- _current = default;
+ _current = default!;
_state = -1;
}
ThrowHelper.ThrowNoElementsException();
}
- return last;
+ return last!;
}
public static TSource Last<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
ThrowHelper.ThrowNoMatchException();
}
- return last;
+ return last!;
}
[return: MaybeNull]
bool sourceFound;
TSource input = _source.TryGetElementAt(index, out sourceFound);
found = sourceFound;
- return sourceFound ? _selector(input) : default!;
+ return sourceFound ? _selector(input!) : default!;
}
[return: MaybeNull]
bool sourceFound;
TSource input = _source.TryGetFirst(out sourceFound);
found = sourceFound;
- return sourceFound ? _selector(input) : default!;
+ return sourceFound ? _selector(input!) : default!;
}
[return: MaybeNull]
bool sourceFound;
TSource input = _source.TryGetLast(out sourceFound);
found = sourceFound;
- return sourceFound ? _selector(input) : default!;
+ return sourceFound ? _selector(input!) : default!;
}
private TResult[] LazyToArray()
}
_slots[i]._hashCode = -1;
- _slots[i]._value = default;
+ _slots[i]._value = default!;
_slots[i]._next = -1;
return true;
}
/// <summary>
/// The item held by this slot.
/// </summary>
- [MaybeNull, AllowNull]
internal TElement _value;
}
}
}
// Return the value from the slot.
- return segment._slots[i].Item;
+ return segment._slots[i].Item!;
}
private IEnumerator<T> Enumerate(ConcurrentQueueSegment<T> head, int headHead, ConcurrentQueueSegment<T> tail, int tailTail)
{
// Successfully reserved the slot. Note that after the above CompareExchange, other threads
// trying to dequeue from this slot will end up spinning until we do the subsequent Write.
- item = slots[slotsIndex].Item;
+ item = slots[slotsIndex].Item!;
if (!Volatile.Read(ref _preservedForObservation))
{
// If we're preserving, though, we don't zero out the slot, as we need it for
int diff = sequenceNumber - (currentHead + 1);
if (diff == 0)
{
- result = resultUsed ? slots[slotsIndex].Item : default!;
+ result = resultUsed ? slots[slotsIndex].Item! : default!;
return true;
}
else if (diff < 0)
public bool IsValueCreated => _lazy.IsValueCreated;
/// <summary>Returns the value of the Lazy object.</summary>
+ [MaybeNull]
public T Value => _lazy.ValueForDebugDisplay;
/// <summary>Returns the execution mode of the Lazy object</summary>
internal AsyncLocalValueChangedArgs([AllowNull] T previousValue, [AllowNull] T currentValue, bool contextChanged)
{
- PreviousValue = previousValue;
- CurrentValue = currentValue;
+ PreviousValue = previousValue!;
+ CurrentValue = currentValue!;
ThreadContextChanged = contextChanged;
}
}
// Fast path.
if (Volatile.Read(ref initialized))
{
- return target;
+ return target!;
}
return EnsureInitializedCore(ref target, ref initialized, ref syncLock);
}
}
- return target;
+ return target!;
}
/// <summary>
// Fast path.
if (Volatile.Read(ref initialized))
{
- return target;
+ return target!;
}
return EnsureInitializedCore(ref target, ref initialized, ref syncLock, valueFactory);
}
}
- return target;
+ return target!;
}
/// <summary>
public class Task<TResult> : Task
{
// The value itself, if set.
- [MaybeNull] internal TResult m_result = default!;
+ [MaybeNull, AllowNull] internal TResult m_result = default!;
private static readonly TaskFactory<TResult> s_Factory = new TaskFactory<TResult>();
public TResult Result =>
IsWaitNotificationEnabledOrNotRanToCompletion ?
GetResultCore(waitCompletionNotification: true) :
- m_result;
+ m_result!;
/// <summary>
/// Gets the result value of this <see cref="Task{TResult}"/> once the task has completed successfully.
{
Debug.Assert(!IsWaitNotificationEnabledOrNotRanToCompletion,
"Should only be used when the task completed successfully and there's no wait notification enabled");
- return m_result;
+ return m_result!;
}
}
// We shouldn't be here if the result has not been set.
Debug.Assert(IsCompletedSuccessfully, "Task<T>.Result getter: Expected result to have been set.");
- return m_result;
+ return m_result!;
}
/// <summary>
public bool IsValueCreated => _tlocal.IsValueCreated;
/// <summary>Returns the value of the ThreadLocal object.</summary>
+ [MaybeNull]
public T Value => _tlocal.ValueForDebugDisplay;
/// <summary>Return all values for all threads that have accessed this instance.</summary>
{
// Call the worker method that has more performant but less user friendly signature.
T o = this.Target;
- target = o;
+ target = o!;
return o != null;
}
}
error?.Throw();
- return result;
+ return result!;
}
/// <summary>Gets the result of the operation.</summary>
VoidAsyncOperationWithData<T> w = parent._blockedWriters.DequeueHead();
if (w.TrySetResult(default))
{
- parent._items.EnqueueTail(w.Item);
+ parent._items.EnqueueTail(w.Item!);
return item;
}
}