Fix nullable annotation on IEnumerator.Current (#37969)
authorStephen Toub <stoub@microsoft.com>
Wed, 17 Jun 2020 21:09:44 +0000 (17:09 -0400)
committerGitHub <noreply@github.com>
Wed, 17 Jun 2020 21:09:44 +0000 (17:09 -0400)
For the non-generic IEnumerator, we don't have any idea whether the type contains nulls or not.  If we're forced to annotate it, `?` is correct, because it says "it's possible this is null" and we can't prove it's not.  But that ends up leading to lots of spurious warnings, in particular when enumerating over supplied collections that won't ever contain null, e.g. enumerating a CookieCollection.  Since the non-generic IEnumerator is effectively legacy, our best path forward while maintaining correctness and avoiding causing unnecessary warnings is to simply not annotate `IEnumerator.Current` at all, leaving it "oblivious"; in that way, we don't make any claims about its state, and leave it up to tooling how to best convey that.

18 files changed:
src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceInternal.cs
src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceListener.cs
src/libraries/System.Linq/src/System/Linq/Cast.cs
src/libraries/System.Net.Mail/src/System/Net/Mail/MailWriter.cs
src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpClient.cs
src/libraries/System.Net.Mail/src/System/Net/Mime/ContentDisposition.cs
src/libraries/System.Net.Mail/src/System/Net/Mime/ContentType.cs
src/libraries/System.Net.Mail/src/System/Net/Mime/MimeWriter.cs
src/libraries/System.Net.Primitives/src/System/Net/CookieContainer.cs
src/libraries/System.Net.Requests/src/System/Net/HttpWebRequest.cs
src/libraries/System.Net.Security/src/System/Security/Authentication/ExtendedProtection/ExtendedProtectionPolicy.cs
src/libraries/System.Net.Security/src/System/Security/Authentication/ExtendedProtection/ServiceNameCollection.cs
src/libraries/System.Net.WebSockets.Client/src/System/Net/WebSockets/WebSocketHandle.Managed.cs
src/libraries/System.Private.CoreLib/src/System/Collections/IEnumerator.cs
src/libraries/System.Private.Xml/src/System/Xml/Schema/ContentValidator.cs
src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaAny.cs
src/libraries/System.Runtime/ref/System.Runtime.cs
src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509CertificateCollection.cs

index aaceeb4..3983502 100644 (file)
@@ -21,9 +21,9 @@ namespace System.Diagnostics
             {
                 lock (TraceInternal.critSec)
                 {
-                    foreach (TraceListener? listener in Listeners) // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
+                    foreach (TraceListener listener in Listeners)
                     {
-                        listener!.IndentLevel = indentLevel;
+                        listener.IndentLevel = indentLevel;
                     }
                 }
             }
@@ -32,9 +32,9 @@ namespace System.Diagnostics
             {
                 lock (TraceInternal.critSec)
                 {
-                    foreach (TraceListener? listener in Listeners) // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
+                    foreach (TraceListener listener in Listeners)
                     {
-                        listener!.IndentSize = indentSize;
+                        listener.IndentSize = indentSize;
                     }
                 }
             }
@@ -164,17 +164,17 @@ namespace System.Diagnostics
                 {
                     lock (critSec)
                     {
-                        foreach (TraceListener? listener in Listeners) // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
+                        foreach (TraceListener listener in Listeners)
                         {
-                            listener!.Flush();
+                            listener.Flush();
                         }
                     }
                 }
                 else
                 {
-                    foreach (TraceListener? listener in Listeners) // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
+                    foreach (TraceListener listener in Listeners)
                     {
-                        if (!listener!.IsThreadSafe)
+                        if (!listener.IsThreadSafe)
                         {
                             lock (listener)
                             {
@@ -197,9 +197,9 @@ namespace System.Diagnostics
                 // Use global lock
                 lock (critSec)
                 {
-                    foreach (TraceListener? listener in Listeners) // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
+                    foreach (TraceListener listener in Listeners)
                     {
-                        listener!.Close();
+                        listener.Close();
                     }
                 }
             }
@@ -229,18 +229,18 @@ namespace System.Diagnostics
             {
                 lock (critSec)
                 {
-                    foreach (TraceListener? listener in Listeners) // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
+                    foreach (TraceListener listener in Listeners)
                     {
-                        listener!.Fail(message);
+                        listener.Fail(message);
                         if (AutoFlush) listener.Flush();
                     }
                 }
             }
             else
             {
-                foreach (TraceListener? listener in Listeners) // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
+                foreach (TraceListener listener in Listeners)
                 {
-                    if (!listener!.IsThreadSafe)
+                    if (!listener.IsThreadSafe)
                     {
                         lock (listener)
                         {
@@ -263,18 +263,18 @@ namespace System.Diagnostics
             {
                 lock (critSec)
                 {
-                    foreach (TraceListener? listener in Listeners) // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
+                    foreach (TraceListener listener in Listeners)
                     {
-                        listener!.Fail(message, detailMessage);
+                        listener.Fail(message, detailMessage);
                         if (AutoFlush) listener.Flush();
                     }
                 }
             }
             else
             {
-                foreach (TraceListener? listener in Listeners) // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
+                foreach (TraceListener listener in Listeners)
                 {
-                    if (!listener!.IsThreadSafe)
+                    if (!listener.IsThreadSafe)
                     {
                         lock (listener)
                         {
@@ -332,17 +332,17 @@ namespace System.Diagnostics
                 {
                     if (args == null)
                     {
-                        foreach (TraceListener? listener in Listeners) // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
+                        foreach (TraceListener listener in Listeners)
                         {
-                            listener!.TraceEvent(EventCache, AppName, eventType, id, format);
+                            listener.TraceEvent(EventCache, AppName, eventType, id, format);
                             if (AutoFlush) listener.Flush();
                         }
                     }
                     else
                     {
-                        foreach (TraceListener? listener in Listeners) // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
+                        foreach (TraceListener listener in Listeners)
                         {
-                            listener!.TraceEvent(EventCache, AppName, eventType, id, format!, args);
+                            listener.TraceEvent(EventCache, AppName, eventType, id, format!, args);
                             if (AutoFlush) listener.Flush();
                         }
                     }
@@ -352,9 +352,9 @@ namespace System.Diagnostics
             {
                 if (args == null)
                 {
-                    foreach (TraceListener? listener in Listeners) // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
+                    foreach (TraceListener listener in Listeners)
                     {
-                        if (!listener!.IsThreadSafe)
+                        if (!listener.IsThreadSafe)
                         {
                             lock (listener)
                             {
@@ -371,9 +371,9 @@ namespace System.Diagnostics
                 }
                 else
                 {
-                    foreach (TraceListener? listener in Listeners) // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
+                    foreach (TraceListener listener in Listeners)
                     {
-                        if (!listener!.IsThreadSafe)
+                        if (!listener.IsThreadSafe)
                         {
                             lock (listener)
                             {
@@ -398,18 +398,18 @@ namespace System.Diagnostics
             {
                 lock (critSec)
                 {
-                    foreach (TraceListener? listener in Listeners) // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
+                    foreach (TraceListener listener in Listeners)
                     {
-                        listener!.Write(message);
+                        listener.Write(message);
                         if (AutoFlush) listener.Flush();
                     }
                 }
             }
             else
             {
-                foreach (TraceListener? listener in Listeners) // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
+                foreach (TraceListener listener in Listeners)
                 {
-                    if (!listener!.IsThreadSafe)
+                    if (!listener.IsThreadSafe)
                     {
                         lock (listener)
                         {
@@ -432,18 +432,18 @@ namespace System.Diagnostics
             {
                 lock (critSec)
                 {
-                    foreach (TraceListener? listener in Listeners) // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
+                    foreach (TraceListener listener in Listeners)
                     {
-                        listener!.Write(value);
+                        listener.Write(value);
                         if (AutoFlush) listener.Flush();
                     }
                 }
             }
             else
             {
-                foreach (TraceListener? listener in Listeners) // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
+                foreach (TraceListener listener in Listeners)
                 {
-                    if (!listener!.IsThreadSafe)
+                    if (!listener.IsThreadSafe)
                     {
                         lock (listener)
                         {
@@ -466,18 +466,18 @@ namespace System.Diagnostics
             {
                 lock (critSec)
                 {
-                    foreach (TraceListener? listener in Listeners) // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
+                    foreach (TraceListener listener in Listeners)
                     {
-                        listener!.Write(message, category);
+                        listener.Write(message, category);
                         if (AutoFlush) listener.Flush();
                     }
                 }
             }
             else
             {
-                foreach (TraceListener? listener in Listeners) // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
+                foreach (TraceListener listener in Listeners)
                 {
-                    if (!listener!.IsThreadSafe)
+                    if (!listener.IsThreadSafe)
                     {
                         lock (listener)
                         {
@@ -500,18 +500,18 @@ namespace System.Diagnostics
             {
                 lock (critSec)
                 {
-                    foreach (TraceListener? listener in Listeners) // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
+                    foreach (TraceListener listener in Listeners)
                     {
-                        listener!.Write(value, category);
+                        listener.Write(value, category);
                         if (AutoFlush) listener.Flush();
                     }
                 }
             }
             else
             {
-                foreach (TraceListener? listener in Listeners) // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
+                foreach (TraceListener listener in Listeners)
                 {
-                    if (!listener!.IsThreadSafe)
+                    if (!listener.IsThreadSafe)
                     {
                         lock (listener)
                         {
@@ -534,18 +534,18 @@ namespace System.Diagnostics
             {
                 lock (critSec)
                 {
-                    foreach (TraceListener? listener in Listeners) // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
+                    foreach (TraceListener listener in Listeners)
                     {
-                        listener!.WriteLine(message);
+                        listener.WriteLine(message);
                         if (AutoFlush) listener.Flush();
                     }
                 }
             }
             else
             {
-                foreach (TraceListener? listener in Listeners) // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
+                foreach (TraceListener listener in Listeners)
                 {
-                    if (!listener!.IsThreadSafe)
+                    if (!listener.IsThreadSafe)
                     {
                         lock (listener)
                         {
@@ -568,18 +568,18 @@ namespace System.Diagnostics
             {
                 lock (critSec)
                 {
-                    foreach (TraceListener? listener in Listeners) // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
+                    foreach (TraceListener listener in Listeners)
                     {
-                        listener!.WriteLine(value);
+                        listener.WriteLine(value);
                         if (AutoFlush) listener.Flush();
                     }
                 }
             }
             else
             {
-                foreach (TraceListener? listener in Listeners) // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
+                foreach (TraceListener listener in Listeners)
                 {
-                    if (!listener!.IsThreadSafe)
+                    if (!listener.IsThreadSafe)
                     {
                         lock (listener)
                         {
@@ -602,18 +602,18 @@ namespace System.Diagnostics
             {
                 lock (critSec)
                 {
-                    foreach (TraceListener? listener in Listeners) // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
+                    foreach (TraceListener listener in Listeners)
                     {
-                        listener!.WriteLine(message, category);
+                        listener.WriteLine(message, category);
                         if (AutoFlush) listener.Flush();
                     }
                 }
             }
             else
             {
-                foreach (TraceListener? listener in Listeners) // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
+                foreach (TraceListener listener in Listeners)
                 {
-                    if (!listener!.IsThreadSafe)
+                    if (!listener.IsThreadSafe)
                     {
                         lock (listener)
                         {
@@ -636,18 +636,18 @@ namespace System.Diagnostics
             {
                 lock (critSec)
                 {
-                    foreach (TraceListener? listener in Listeners) // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
+                    foreach (TraceListener listener in Listeners)
                     {
-                        listener!.WriteLine(value, category);
+                        listener.WriteLine(value, category);
                         if (AutoFlush) listener.Flush();
                     }
                 }
             }
             else
             {
-                foreach (TraceListener? listener in Listeners) // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
+                foreach (TraceListener listener in Listeners)
                 {
-                    if (!listener!.IsThreadSafe)
+                    if (!listener.IsThreadSafe)
                     {
                         lock (listener)
                         {
index 840a35f..1fdbe85 100644 (file)
@@ -429,7 +429,7 @@ namespace System.Diagnostics
                 Write("LogicalOperationStack=");
                 Stack operationStack = eventCache.LogicalOperationStack;
                 bool first = true;
-                foreach (object? obj in operationStack)
+                foreach (object obj in operationStack)
                 {
                     if (!first)
                     {
@@ -440,7 +440,7 @@ namespace System.Diagnostics
                         first = false;
                     }
 
-                    Write(obj!.ToString());
+                    Write(obj.ToString());
                 }
 
                 WriteLine(string.Empty);
index ebe2490..3cb42f3 100644 (file)
@@ -47,9 +47,9 @@ namespace System.Linq
 
         private static IEnumerable<TResult> CastIterator<TResult>(IEnumerable source)
         {
-            foreach (object? obj in source)
+            foreach (object obj in source)
             {
-                yield return (TResult)obj!;
+                yield return (TResult)obj;
             }
         }
     }
index ddd4b21..badf258 100644 (file)
@@ -28,11 +28,11 @@ namespace System.Net.Mail
             if (headers == null)
                 throw new ArgumentNullException(nameof(headers));
 
-            foreach (string? key in headers) // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/3214
+            foreach (string key in headers)
             {
                 string[] values = headers!.GetValues(key)!;
                 foreach (string value in values)
-                    WriteHeader(key!, value, allowUnicode);
+                    WriteHeader(key, value, allowUnicode);
             }
         }
 
index ae58a98..118d911 100644 (file)
@@ -740,7 +740,7 @@ namespace System.Net.Mail
         private bool IsSystemNetworkCredentialInCache(CredentialCache cache)
         {
             // Check if SystemNetworkCredential is in given cache.
-            foreach (NetworkCredential? credential in cache) // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/3214
+            foreach (NetworkCredential credential in cache)
             {
                 if (ReferenceEquals(credential, CredentialCache.DefaultNetworkCredentials))
                 {
index 3361898..3431e6c 100644 (file)
@@ -219,13 +219,13 @@ namespace System.Net.Mime
             builder.Append(_dispositionType); // Must not have unicode, already validated
 
             // Validate and encode unicode where required
-            foreach (string? key in Parameters.Keys) // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/3214
+            foreach (string key in Parameters.Keys)
             {
                 builder.Append("; ");
-                EncodeToBuffer(key!, builder, allowUnicode);
+                EncodeToBuffer(key, builder, allowUnicode);
 
                 builder.Append('=');
-                EncodeToBuffer(_parameters![key!]!, builder, allowUnicode);
+                EncodeToBuffer(_parameters![key]!, builder, allowUnicode);
             }
 
             return builder.ToString();
index 009a7ed..79c067c 100644 (file)
@@ -194,12 +194,12 @@ namespace System.Net.Mime
             builder.Append(_subType);  // Must not have unicode, already validated
 
             // Validate and encode unicode where required
-            foreach (string? key in Parameters.Keys) // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/3214
+            foreach (string key in Parameters.Keys)
             {
                 builder.Append("; ");
-                EncodeToBuffer(key!, builder, allowUnicode);
+                EncodeToBuffer(key, builder, allowUnicode);
                 builder.Append('=');
-                EncodeToBuffer(_parameters[key!]!, builder, allowUnicode);
+                EncodeToBuffer(_parameters[key]!, builder, allowUnicode);
             }
 
             return builder.ToString();
index bf7c66c..6802846 100644 (file)
@@ -34,8 +34,8 @@ namespace System.Net.Mime
             if (headers == null)
                 throw new ArgumentNullException(nameof(headers));
 
-            foreach (string? key in headers) // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/3214
-                WriteHeader(key!, headers[key]!, allowUnicode);
+            foreach (string key in headers)
+                WriteHeader(key, headers[key]!, allowUnicode);
         }
 
         #region Cleanup
index af1f75e..cd25959 100644 (file)
@@ -396,9 +396,9 @@ namespace System.Net
             }
             lock (m_domainTable.SyncRoot)
             {
-                foreach (object? item in m_domainTable)
+                foreach (object item in m_domainTable)
                 {
-                    DictionaryEntry entry = (DictionaryEntry)item!;
+                    DictionaryEntry entry = (DictionaryEntry)item;
                     if (domain == null)
                     {
                         tempDomain = (string)entry.Key;
@@ -691,9 +691,9 @@ namespace System.Net
             }
 
             bool isLocalDomain = IsLocalDomain(uri.Host);
-            foreach (Cookie? c in cookies)
+            foreach (Cookie c in cookies)
             {
-                Cookie new_cookie = c!.Clone();
+                Cookie new_cookie = c.Clone();
                 new_cookie.VerifySetDefaults(new_cookie.Variant, uri, isLocalDomain, m_fqdnMyDomain, true, true);
                 Add(new_cookie, true);
             }
index 33a7936..0192479 100644 (file)
@@ -1137,12 +1137,12 @@ namespace System.Net
 
                 // Copy the HttpWebRequest request headers from the WebHeaderCollection into HttpRequestMessage.Headers and
                 // HttpRequestMessage.Content.Headers.
-                foreach (string? headerName in _webHeaderCollection) // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/3214
+                foreach (string headerName in _webHeaderCollection)
                 {
                     // The System.Net.Http APIs require HttpRequestMessage headers to be properly divided between the request headers
                     // collection and the request content headers collection for all well-known header names.  And custom headers
                     // are only allowed in the request headers collection and not in the request content headers collection.
-                    if (IsWellKnownContentHeader(headerName!))
+                    if (IsWellKnownContentHeader(headerName))
                     {
                         if (request.Content == null)
                         {
@@ -1150,11 +1150,11 @@ namespace System.Net
                             request.Content = new ByteArrayContent(Array.Empty<byte>());
                         }
 
-                        request.Content.Headers.TryAddWithoutValidation(headerName!, _webHeaderCollection[headerName!]);
+                        request.Content.Headers.TryAddWithoutValidation(headerName, _webHeaderCollection[headerName!]);
                     }
                     else
                     {
-                        request.Headers.TryAddWithoutValidation(headerName!, _webHeaderCollection[headerName!]);
+                        request.Headers.TryAddWithoutValidation(headerName, _webHeaderCollection[headerName!]);
                     }
                 }
 
index bbc9021..71bc70c 100644 (file)
@@ -128,7 +128,7 @@ namespace System.Security.Authentication.ExtendedProtection
             else
             {
                 bool first = true;
-                foreach (string? serviceName in _customServiceNames)
+                foreach (string serviceName in _customServiceNames)
                 {
                     if (first)
                     {
index eaf14ae..8cfe3c7 100644 (file)
@@ -59,7 +59,7 @@ namespace System.Security.Authentication.ExtendedProtection
         {
             string? searchName = NormalizeServiceName(searchServiceName);
 
-            foreach (string? serviceName in InnerList)
+            foreach (string serviceName in InnerList)
             {
                 if (string.Equals(serviceName, searchName, StringComparison.OrdinalIgnoreCase))
                 {
@@ -95,13 +95,13 @@ namespace System.Security.Authentication.ExtendedProtection
 
             // NullReferenceException is thrown when serviceNames is null,
             // which is consistent with the behavior of the .NET Framework.
-            foreach (object? item in serviceNames)
+            foreach (object item in serviceNames)
             {
                 // To match the behavior of the .NET Framework, when an item
                 // in the collection is not a string:
                 //  - Throw InvalidCastException when expectStrings is true.
                 //  - Throw ArgumentException when expectStrings is false.
-                AddIfNew(expectStrings ? (string)item! : (item as string)!);
+                AddIfNew(expectStrings ? (string)item : (item as string)!);
             }
         }
 
@@ -125,9 +125,9 @@ namespace System.Security.Authentication.ExtendedProtection
         {
             Debug.Assert(serviceNames != null);
 
-            foreach (string? serviceName in serviceNames)
+            foreach (string serviceName in serviceNames)
             {
-                AddIfNew(serviceName!);
+                AddIfNew(serviceName);
             }
         }
 
index 893da94..ecea0dd 100644 (file)
@@ -82,9 +82,9 @@ namespace System.Net.WebSockets
                 var request = new HttpRequestMessage(HttpMethod.Get, uri);
                 if (options._requestHeaders?.Count > 0) // use field to avoid lazily initializing the collection
                 {
-                    foreach (string? key in options.RequestHeaders) // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/3214
+                    foreach (string key in options.RequestHeaders)
                     {
-                        request.Headers.TryAddWithoutValidation(key!, options.RequestHeaders[key!]);
+                        request.Headers.TryAddWithoutValidation(key, options.RequestHeaders[key]);
                     }
                 }
 
index cce1fa9..2ca7bac 100644 (file)
@@ -22,7 +22,10 @@ namespace System.Collections
         // GetCurrent with no intervening calls to MoveNext
         // will return the same object.
         //
-        object? Current
+
+#nullable disable // explicitly leaving Current as "oblivious" to avoid spurious warnings in foreach over non-generic enumerables
+        object Current
+#nullable restore
         {
             get;
         }
index 4e03698..c3bac37 100644 (file)
@@ -108,9 +108,8 @@ namespace System.Xml.Schema
                     }
                     break;
                 case NamespaceList.ListType.Set:
-                    foreach (string? wildcard in list.Enumerate)
+                    foreach (string wildcard in list.Enumerate)
                     {
-                        Debug.Assert(wildcard != null);
                         AddWildcard(wildcard, particle);
                     }
                     break;
@@ -152,9 +151,8 @@ namespace System.Xml.Schema
 
             if (_wildcards != null)
             {
-                foreach (string? wildcard in _wildcards.Keys)
+                foreach (string wildcard in _wildcards.Keys)
                 {
-                    Debug.Assert(wildcard != null);
                     if (list.Allows(wildcard))
                     {
                         match.Add(_wildcards[wildcard]);
@@ -223,9 +221,7 @@ namespace System.Xml.Schema
         /// </summary>
         public string NameOf(int symbol)
         {
-#pragma warning disable CS8605 // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
             foreach (DictionaryEntry de in _names)
-#pragma warning restore CS8605
             {
                 if ((int)de.Value! == symbol)
                 {
@@ -235,9 +231,7 @@ namespace System.Xml.Schema
 
             if (_wildcards != null)
             {
-#pragma warning disable CS8605 // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
                 foreach (DictionaryEntry de in _wildcards)
-#pragma warning restore CS8605
                 {
                     if ((int)de!.Value! == symbol)
                     {
@@ -389,9 +383,7 @@ namespace System.Xml.Schema
         public override void ExpandTree(InteriorNode parent, SymbolsDictionary symbols, Positions positions)
         {
             SyntaxTreeNode? replacementNode = null;
-#pragma warning disable CS8605 // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
             foreach (int symbol in GetResolvedSymbols(symbols))
-#pragma warning restore CS8605
             {
                 if (symbols.GetParticle(symbol) != particle)
                 {
@@ -2249,9 +2241,7 @@ namespace System.Xml.Schema
         public override ArrayList? ExpectedElements(ValidationState context, bool isRequiredOnly)
         {
             ArrayList? names = null;
-#pragma warning disable CS8605 // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
             foreach (DictionaryEntry entry in _elements)
-#pragma warning restore CS8605
             {
                 if (!context.AllElementsSet![(int)entry.Value!] && (!isRequiredOnly || _isRequired[(int)entry.Value]))
                 {
@@ -2270,9 +2260,7 @@ namespace System.Xml.Schema
         public override ArrayList ExpectedParticles(ValidationState context, bool isRequiredOnly, XmlSchemaSet schemaSet)
         {
             ArrayList expectedParticles = new ArrayList();
-#pragma warning disable CS8605 // TODO-NULLABLE https://github.com/dotnet/csharplang/issues/3214
             foreach (DictionaryEntry entry in _elements)
-#pragma warning restore CS8605
             {
                 if (!context.AllElementsSet![(int)entry.Value!] && (!isRequiredOnly || _isRequired[(int)entry.Value]))
                 {
index 970d318..dbe3727 100644 (file)
@@ -69,7 +69,7 @@ namespace System.Xml.Schema
                     case NamespaceList.ListType.Set:
                         StringBuilder sb = new StringBuilder();
                         int i = 1;
-                        foreach (string? wildcardNS in _namespaceList.Enumerate)
+                        foreach (string wildcardNS in _namespaceList.Enumerate)
                         {
                             sb.Append(wildcardNS + ":*");
                             if (i < _namespaceList.Enumerate.Count)
index 4610536..f4f47cb 100644 (file)
@@ -5186,7 +5186,9 @@ namespace System.Collections
     }
     public partial interface IEnumerator
     {
-        object? Current { get; }
+#nullable disable // explicitly leaving Current as "oblivious" to avoid spurious warnings in foreach over non-generic enumerables
+        object Current { get; }
+#nullable restore
         bool MoveNext();
         void Reset();
     }
index cb0e4ec..268c1ef 100644 (file)
@@ -83,9 +83,9 @@ namespace System.Security.Cryptography.X509Certificates
         public override int GetHashCode()
         {
             int hashCode = 0;
-            foreach (X509Certificate? cert in List)
+            foreach (X509Certificate cert in List)
             {
-                hashCode += cert!.GetHashCode();
+                hashCode += cert.GetHashCode();
             }
             return hashCode;
         }