diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Crefs.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Crefs.cs index 1c6a6654a5135cbe4e58122ac2339538838157b4..6316e62f345438e9fe9c3aa5d80b9c68b9efe9fc 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Crefs.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Crefs.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Collections.Generic; using System.Collections.Immutable; @@ -15,15 +16,15 @@ namespace Microsoft.CodeAnalysis.CSharp { internal partial class Binder { - internal ImmutableArray BindCref(CrefSyntax syntax, out Symbol ambiguityWinner, DiagnosticBag diagnostics) + internal ImmutableArray BindCref(CrefSyntax syntax, out Symbol? ambiguityWinner, DiagnosticBag diagnostics) { ImmutableArray symbols = BindCrefInternal(syntax, out ambiguityWinner, diagnostics); Debug.Assert(!symbols.IsDefault, "Prefer empty to null."); - Debug.Assert((symbols.Length > 1) == ((object)ambiguityWinner != null), "ambiguityWinner should be set iff more than one symbol is returned."); + Debug.Assert((symbols.Length > 1) == ((object?)ambiguityWinner != null), "ambiguityWinner should be set iff more than one symbol is returned."); return symbols; } - private ImmutableArray BindCrefInternal(CrefSyntax syntax, out Symbol ambiguityWinner, DiagnosticBag diagnostics) + private ImmutableArray BindCrefInternal(CrefSyntax syntax, out Symbol? ambiguityWinner, DiagnosticBag diagnostics) { switch (syntax.Kind()) { @@ -41,7 +42,7 @@ private ImmutableArray BindCrefInternal(CrefSyntax syntax, out Symbol am } } - private ImmutableArray BindTypeCref(TypeCrefSyntax syntax, out Symbol ambiguityWinner, DiagnosticBag diagnostics) + private ImmutableArray BindTypeCref(TypeCrefSyntax syntax, out Symbol? ambiguityWinner, DiagnosticBag diagnostics) { NamespaceOrTypeSymbol result = BindNamespaceOrTypeSymbolInCref(syntax.Type); @@ -60,7 +61,7 @@ private ImmutableArray BindTypeCref(TypeCrefSyntax syntax, out Symbol am return ImmutableArray.Create(result); } - private ImmutableArray BindQualifiedCref(QualifiedCrefSyntax syntax, out Symbol ambiguityWinner, DiagnosticBag diagnostics) + private ImmutableArray BindQualifiedCref(QualifiedCrefSyntax syntax, out Symbol? ambiguityWinner, DiagnosticBag diagnostics) { // NOTE: we won't check whether container is an error type - we'll just let BindMemberCref fail // and report a blanket diagnostic. @@ -98,9 +99,9 @@ private NamespaceOrTypeSymbol BindNamespaceOrTypeSymbolInCref(TypeSyntax syntax) return namespaceOrTypeSymbol; } - private ImmutableArray BindMemberCref(MemberCrefSyntax syntax, NamespaceOrTypeSymbol containerOpt, out Symbol ambiguityWinner, DiagnosticBag diagnostics) + private ImmutableArray BindMemberCref(MemberCrefSyntax syntax, NamespaceOrTypeSymbol? containerOpt, out Symbol? ambiguityWinner, DiagnosticBag diagnostics) { - if ((object)containerOpt != null && containerOpt.Kind == SymbolKind.TypeParameter) + if ((object?)containerOpt != null && containerOpt.Kind == SymbolKind.TypeParameter) { // As in normal lookup (see CreateErrorIfLookupOnTypeParameter), you can't dot into a type parameter // (though you can dot into an expression of type parameter type). @@ -141,9 +142,9 @@ private ImmutableArray BindMemberCref(MemberCrefSyntax syntax, Namespace return result; } - private ImmutableArray BindNameMemberCref(NameMemberCrefSyntax syntax, NamespaceOrTypeSymbol containerOpt, out Symbol ambiguityWinner, DiagnosticBag diagnostics) + private ImmutableArray BindNameMemberCref(NameMemberCrefSyntax syntax, NamespaceOrTypeSymbol? containerOpt, out Symbol? ambiguityWinner, DiagnosticBag diagnostics) { - SimpleNameSyntax nameSyntax = syntax.Name as SimpleNameSyntax; + SimpleNameSyntax? nameSyntax = syntax.Name as SimpleNameSyntax; int arity; string memberName; @@ -157,7 +158,7 @@ private ImmutableArray BindNameMemberCref(NameMemberCrefSyntax syntax, N { // If the name isn't a SimpleNameSyntax, then we must have a type name followed by a parameter list. // Thus, we're looking for a constructor. - Debug.Assert((object)containerOpt == null); + Debug.Assert((object?)containerOpt == null); // Could be an error type, but we'll just lookup fail below. containerOpt = BindNamespaceOrTypeSymbolInCref(syntax.Name); @@ -184,13 +185,13 @@ private ImmutableArray BindNameMemberCref(NameMemberCrefSyntax syntax, N sortedSymbols, arity, syntax, - typeArgumentListSyntax: arity == 0 ? null : ((GenericNameSyntax)nameSyntax).TypeArgumentList, + typeArgumentListSyntax: arity == 0 ? null : ((GenericNameSyntax)nameSyntax!).TypeArgumentList, parameterListSyntax: syntax.Parameters, ambiguityWinner: out ambiguityWinner, diagnostics: diagnostics); } - private ImmutableArray BindIndexerMemberCref(IndexerMemberCrefSyntax syntax, NamespaceOrTypeSymbol containerOpt, out Symbol ambiguityWinner, DiagnosticBag diagnostics) + private ImmutableArray BindIndexerMemberCref(IndexerMemberCrefSyntax syntax, NamespaceOrTypeSymbol? containerOpt, out Symbol? ambiguityWinner, DiagnosticBag diagnostics) { const int arity = 0; @@ -218,17 +219,17 @@ private ImmutableArray BindIndexerMemberCref(IndexerMemberCrefSyntax syn // NOTE: not guaranteed to be a method (e.g. class op_Addition) // NOTE: constructor fallback logic applies - private ImmutableArray BindOperatorMemberCref(OperatorMemberCrefSyntax syntax, NamespaceOrTypeSymbol containerOpt, out Symbol ambiguityWinner, DiagnosticBag diagnostics) + private ImmutableArray BindOperatorMemberCref(OperatorMemberCrefSyntax syntax, NamespaceOrTypeSymbol? containerOpt, out Symbol? ambiguityWinner, DiagnosticBag diagnostics) { const int arity = 0; - CrefParameterListSyntax parameterListSyntax = syntax.Parameters; + CrefParameterListSyntax? parameterListSyntax = syntax.Parameters; // NOTE: Prefer binary to unary, unless there is exactly one parameter. // CONSIDER: we're following dev11 by never using a binary operator name if there's // exactly one parameter, but doing so would allow us to match single-parameter constructors. SyntaxKind operatorTokenKind = syntax.OperatorToken.Kind(); - string memberName = parameterListSyntax != null && parameterListSyntax.Parameters.Count == 1 + string? memberName = parameterListSyntax != null && parameterListSyntax.Parameters.Count == 1 ? null : OperatorFacts.BinaryOperatorNameFromSyntaxKindIfAny(operatorTokenKind); memberName = memberName ?? OperatorFacts.UnaryOperatorNameFromSyntaxKindIfAny(operatorTokenKind); @@ -258,7 +259,7 @@ private ImmutableArray BindOperatorMemberCref(OperatorMemberCrefSyntax s } // NOTE: not guaranteed to be a method (e.g. class op_Implicit) - private ImmutableArray BindConversionOperatorMemberCref(ConversionOperatorMemberCrefSyntax syntax, NamespaceOrTypeSymbol containerOpt, out Symbol ambiguityWinner, DiagnosticBag diagnostics) + private ImmutableArray BindConversionOperatorMemberCref(ConversionOperatorMemberCrefSyntax syntax, NamespaceOrTypeSymbol? containerOpt, out Symbol? ambiguityWinner, DiagnosticBag diagnostics) { const int arity = 0; @@ -304,15 +305,15 @@ private ImmutableArray BindConversionOperatorMemberCref(ConversionOperat /// /// Never returns null. /// - private ImmutableArray ComputeSortedCrefMembers(CSharpSyntaxNode syntax, NamespaceOrTypeSymbol containerOpt, string memberName, int arity, bool hasParameterList, DiagnosticBag diagnostics) + private ImmutableArray ComputeSortedCrefMembers(CSharpSyntaxNode syntax, NamespaceOrTypeSymbol? containerOpt, string memberName, int arity, bool hasParameterList, DiagnosticBag diagnostics) { - HashSet useSiteDiagnostics = null; + HashSet? useSiteDiagnostics = null; var result = ComputeSortedCrefMembers(containerOpt, memberName, arity, hasParameterList, ref useSiteDiagnostics); diagnostics.Add(syntax, useSiteDiagnostics); return result; } - private ImmutableArray ComputeSortedCrefMembers(NamespaceOrTypeSymbol containerOpt, string memberName, int arity, bool hasParameterList, ref HashSet useSiteDiagnostics) + private ImmutableArray ComputeSortedCrefMembers(NamespaceOrTypeSymbol? containerOpt, string memberName, int arity, bool hasParameterList, ref HashSet? useSiteDiagnostics) { // Since we may find symbols without going through the lookup API, // expose the symbols via an ArrayBuilder. @@ -373,12 +374,12 @@ private ImmutableArray ComputeSortedCrefMembers(NamespaceOrTypeSymbol co // As in the native compiler, we treat this as a fallback case - something that actually has the // specified name is preferred. - NamedTypeSymbol constructorType = null; + NamedTypeSymbol? constructorType = null; if (arity == 0) // Member arity { - NamedTypeSymbol containerType = containerOpt as NamedTypeSymbol; - if ((object)containerType != null) + NamedTypeSymbol? containerType = containerOpt as NamedTypeSymbol; + if ((object?)containerType != null) { // Case 1: If the name is qualified by a type with the same name, then we want a // constructor (unless the type is generic, the cref is on/in the type (but not @@ -389,21 +390,21 @@ private ImmutableArray ComputeSortedCrefMembers(NamespaceOrTypeSymbol co constructorType = containerType; } } - else if ((object)containerOpt == null && hasParameterList) + else if ((object?)containerOpt == null && hasParameterList) { // Case 2: If the name is not qualified by anything, but we're in the scope // of a type with the same name (regardless of arity), then we want a constructor, // as long as there were parens after the member name. - NamedTypeSymbol binderContainingType = this.ContainingType; - if ((object)binderContainingType != null && memberName == binderContainingType.Name) + NamedTypeSymbol? binderContainingType = this.ContainingType; + if ((object?)binderContainingType != null && memberName == binderContainingType.Name) { constructorType = binderContainingType; } } } - if ((object)constructorType != null) + if ((object?)constructorType != null) { ImmutableArray instanceConstructors = constructorType.InstanceConstructors; int numInstanceConstructors = instanceConstructors.Length; @@ -443,9 +444,9 @@ private ImmutableArray ComputeSortedCrefMembers(NamespaceOrTypeSymbol co ImmutableArray symbols, int arity, MemberCrefSyntax memberSyntax, - TypeArgumentListSyntax typeArgumentListSyntax, - BaseCrefParameterListSyntax parameterListSyntax, - out Symbol ambiguityWinner, + TypeArgumentListSyntax? typeArgumentListSyntax, + BaseCrefParameterListSyntax? parameterListSyntax, + out Symbol? ambiguityWinner, DiagnosticBag diagnostics) { Debug.Assert(!symbols.IsEmpty); @@ -578,8 +579,8 @@ private static bool IsNestedTypeOfUnconstructedGenericType(NamedTypeSymbol type) ImmutableArray symbols, int arity, MemberCrefSyntax memberSyntax, - TypeArgumentListSyntax typeArgumentListSyntax, - out Symbol ambiguityWinner, + TypeArgumentListSyntax? typeArgumentListSyntax, + out Symbol? ambiguityWinner, DiagnosticBag diagnostics) { // If the syntax indicates arity zero, then we match methods of any arity. @@ -679,13 +680,13 @@ private static bool IsNestedTypeOfUnconstructedGenericType(NamedTypeSymbol type) /// Replace any named type in the symbol list with its instance constructors. /// Construct all candidates with the implicitly-declared CrefTypeParameterSymbols. /// - private void GetCrefOverloadResolutionCandidates(ImmutableArray symbols, int arity, TypeArgumentListSyntax typeArgumentListSyntax, ArrayBuilder candidates) + private void GetCrefOverloadResolutionCandidates(ImmutableArray symbols, int arity, TypeArgumentListSyntax? typeArgumentListSyntax, ArrayBuilder candidates) { foreach (Symbol candidate in symbols) { Symbol constructedCandidate = ConstructWithCrefTypeParameters(arity, typeArgumentListSyntax, candidate); - NamedTypeSymbol constructedCandidateType = constructedCandidate as NamedTypeSymbol; - if ((object)constructedCandidateType == null) + NamedTypeSymbol? constructedCandidateType = constructedCandidate as NamedTypeSymbol; + if ((object?)constructedCandidateType == null) { // Construct before overload resolution so the signatures will match. candidates.Add(constructedCandidate); @@ -705,9 +706,9 @@ private void GetCrefOverloadResolutionCandidates(ImmutableArray symbols, /// Produces a diagnostic for ambiguous matches, but not for unresolved members - WRN_BadXMLRef is /// handled in BindMemberCref. /// - private static ImmutableArray PerformCrefOverloadResolution(ArrayBuilder candidates, ImmutableArray parameterSymbols, int arity, MemberCrefSyntax memberSyntax, out Symbol ambiguityWinner, DiagnosticBag diagnostics) + private static ImmutableArray PerformCrefOverloadResolution(ArrayBuilder candidates, ImmutableArray parameterSymbols, int arity, MemberCrefSyntax memberSyntax, out Symbol? ambiguityWinner, DiagnosticBag diagnostics) { - ArrayBuilder viable = null; + ArrayBuilder? viable = null; foreach (Symbol candidate in candidates) { @@ -827,10 +828,11 @@ private static ImmutableArray PerformCrefOverloadResolution(ArrayBuilder /// /// If the member is generic, construct it with the CrefTypeParameterSymbols that should be in scope. /// - private Symbol ConstructWithCrefTypeParameters(int arity, TypeArgumentListSyntax typeArgumentListSyntax, Symbol symbol) + private Symbol ConstructWithCrefTypeParameters(int arity, TypeArgumentListSyntax? typeArgumentListSyntax, Symbol symbol) { if (arity > 0) { + Debug.Assert(typeArgumentListSyntax is object); SeparatedSyntaxList typeArgumentSyntaxes = typeArgumentListSyntax.Arguments; var typeArgumentsWithAnnotations = ArrayBuilder.GetInstance(arity); diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Deconstruct.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Deconstruct.cs index 13e8da331b82b78faa62eb2c4efa15879589514b..4d533db5d6764fcda9b1bb3ac06e51e1599193c2 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Deconstruct.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Deconstruct.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Collections.Immutable; @@ -30,8 +31,8 @@ internal BoundExpression BindDeconstruction(AssignmentExpressionSyntax node, Dia { var left = node.Left; var right = node.Right; - DeclarationExpressionSyntax declaration = null; - ExpressionSyntax expression = null; + DeclarationExpressionSyntax? declaration = null; + ExpressionSyntax? expression = null; var result = BindDeconstruction(node, left, right, diagnostics, ref declaration, ref expression, resultIsUsedOverride); if (declaration != null) { @@ -88,13 +89,13 @@ internal BoundExpression BindDeconstruction(AssignmentExpressionSyntax node, Dia ExpressionSyntax left, ExpressionSyntax right, DiagnosticBag diagnostics, - ref DeclarationExpressionSyntax declaration, - ref ExpressionSyntax expression, + ref DeclarationExpressionSyntax? declaration, + ref ExpressionSyntax? expression, bool resultIsUsedOverride = false, - BoundDeconstructValuePlaceholder rightPlaceholder = null) + BoundDeconstructValuePlaceholder? rightPlaceholder = null) { DeconstructionVariable locals = BindDeconstructionVariables(left, diagnostics, ref declaration, ref expression); - Debug.Assert(locals.HasNestedVariables); + Debug.Assert(locals.NestedVariables is object); var deconstructionDiagnostics = new DiagnosticBag(); BoundExpression boundRight = rightPlaceholder ?? BindValue(right, deconstructionDiagnostics, BindValueKind.RValue); @@ -120,7 +121,7 @@ internal BoundExpression BindDeconstruction(AssignmentExpressionSyntax node, Dia { uint rightEscape = GetValEscape(boundRHS, this.LocalScopeDepth); - if ((object)boundRHS.Type == null || boundRHS.Type.IsErrorType()) + if ((object?)boundRHS.Type == null || boundRHS.Type.IsErrorType()) { // we could still not infer a type for the RHS FailRemainingInferencesAndSetValEscape(checkedVariables, diagnostics, rightEscape); @@ -154,7 +155,8 @@ internal BoundExpression BindDeconstruction(AssignmentExpressionSyntax node, Dia FailRemainingInferencesAndSetValEscape(checkedVariables, diagnostics, rightEscape); var lhsTuple = DeconstructionVariablesAsTuple(left, checkedVariables, diagnostics, ignoreDiagnosticsFromTuple: diagnostics.HasAnyErrors() || !resultIsUsed); - TypeSymbol returnType = hasErrors ? CreateErrorType() : lhsTuple.Type; + Debug.Assert(hasErrors || lhsTuple.Type is object); + TypeSymbol returnType = hasErrors ? CreateErrorType() : lhsTuple.Type!; uint leftEscape = GetBroadestValEscape(lhsTuple, this.LocalScopeDepth); boundRHS = ValidateEscape(boundRHS, leftEscape, isByRef: false, diagnostics: diagnostics); @@ -216,13 +218,13 @@ private BoundExpression FixTupleLiteral(ArrayBuilder che // If we already have diagnostics at this point, it is not worth collecting likely duplicate diagnostics from making the merged type bool hadErrors = diagnostics.HasAnyErrors(); - TypeSymbol mergedTupleType = MakeMergedTupleType(checkedVariables, (BoundTupleLiteral)boundRHS, syntax, Compilation, hadErrors ? null : diagnostics); - if ((object)mergedTupleType != null) + TypeSymbol? mergedTupleType = MakeMergedTupleType(checkedVariables, (BoundTupleLiteral)boundRHS, syntax, Compilation, hadErrors ? null : diagnostics); + if ((object?)mergedTupleType != null) { boundRHS = GenerateConversionForAssignment(mergedTupleType, boundRHS, diagnostics); } } - else if ((object)boundRHS.Type == null) + else if ((object?)boundRHS.Type == null) { Error(diagnostics, ErrorCode.ERR_DeconstructRequiresExpression, boundRHS.Syntax); } @@ -297,7 +299,7 @@ private BoundExpression FixTupleLiteral(ArrayBuilder che var variable = variables[i]; Conversion nestedConversion; - if (variable.HasNestedVariables) + if (variable.NestedVariables is object) { var elementSyntax = syntax.Kind() == SyntaxKind.TupleExpression ? ((TupleExpressionSyntax)syntax).Arguments[i] : syntax; @@ -307,7 +309,8 @@ private BoundExpression FixTupleLiteral(ArrayBuilder che else { var single = variable.Single; - HashSet useSiteDiagnostics = null; + Debug.Assert(single is object); + HashSet? useSiteDiagnostics = null; nestedConversion = this.Conversions.ClassifyConversionFromType(tupleOrDeconstructedTypes[i], single.Type, ref useSiteDiagnostics); diagnostics.Add(single.Syntax, useSiteDiagnostics); @@ -334,10 +337,9 @@ private void SetInferredTypes(ArrayBuilder variables, Im for (int i = 0; i < matchCount; i++) { var variable = variables[i]; - if (!variable.HasNestedVariables) + if (variable.Single is { } pending) { - var pending = variable.Single; - if ((object)pending.Type != null) + if ((object?)pending.Type != null) { continue; } @@ -359,7 +361,7 @@ private BoundExpression SetInferredType(BoundExpression expression, TypeSymbol t case BoundKind.DiscardExpression: { var pending = (BoundDiscardExpression)expression; - Debug.Assert((object)pending.Type == null); + Debug.Assert((object?)pending.Type == null); return pending.SetInferredTypeWithAnnotations(TypeWithAnnotations.Create(type)); } default: @@ -378,12 +380,13 @@ private BoundExpression SetInferredType(BoundExpression expression, TypeSymbol t for (int i = 0; i < count; i++) { var variable = variables[i]; - if (variable.HasNestedVariables) + if (variable.NestedVariables is object) { FailRemainingInferencesAndSetValEscape(variable.NestedVariables, diagnostics, rhsValEscape); } else { + Debug.Assert(variable.Single is object); switch (variable.Single.Kind) { case BoundKind.Local: @@ -399,7 +402,7 @@ private BoundExpression SetInferredType(BoundExpression expression, TypeSymbol t break; case BoundKind.DiscardExpression: var pending = (BoundDiscardExpression)variable.Single; - if ((object)pending.Type == null) + if ((object?)pending.Type == null) { Error(diagnostics, ErrorCode.ERR_TypeInferenceFailedForImplicitlyTypedDeconstructionVariable, pending.Syntax, "_"); variables[i] = new DeconstructionVariable(pending.FailInference(this, diagnostics), pending.Syntax); @@ -408,7 +411,7 @@ private BoundExpression SetInferredType(BoundExpression expression, TypeSymbol t } // at this point we expect to have a type for every lvalue - Debug.Assert((object)variables[i].Single.Type != null); + Debug.Assert((object?)variables[i].Single!.Type != null); } } } @@ -419,8 +422,8 @@ private BoundExpression SetInferredType(BoundExpression expression, TypeSymbol t [DebuggerDisplay("{GetDebuggerDisplay(),nq}")] internal sealed class DeconstructionVariable { - internal readonly BoundExpression Single; - internal readonly ArrayBuilder NestedVariables; + internal readonly BoundExpression? Single; + internal readonly ArrayBuilder? NestedVariables; internal readonly CSharpSyntaxNode Syntax; internal DeconstructionVariable(BoundExpression variable, SyntaxNode syntax) @@ -437,8 +440,6 @@ internal DeconstructionVariable(ArrayBuilder variables, Syntax = (CSharpSyntaxNode)syntax; } - internal bool HasNestedVariables => NestedVariables != null; - internal static void FreeDeconstructionVariables(ArrayBuilder variables) { variables.FreeAll(v => v.NestedVariables); @@ -450,6 +451,7 @@ private string GetDebuggerDisplay() { return Single.GetDebuggerDisplay(); } + Debug.Assert(NestedVariables is object); return $"Nested variables ({NestedVariables.Count})"; } } @@ -459,29 +461,29 @@ private string GetDebuggerDisplay() /// For cases where the RHS of a deconstruction-assignment is a tuple literal, the type information from the LHS determines the merged type, since all variables have a type. /// Returns null if a merged tuple type could not be fabricated. /// - private static TypeSymbol MakeMergedTupleType(ArrayBuilder lhsVariables, BoundTupleLiteral rhsLiteral, CSharpSyntaxNode syntax, CSharpCompilation compilation, DiagnosticBag diagnostics) + private static TypeSymbol? MakeMergedTupleType(ArrayBuilder lhsVariables, BoundTupleLiteral rhsLiteral, CSharpSyntaxNode syntax, CSharpCompilation compilation, DiagnosticBag? diagnostics) { int leftLength = lhsVariables.Count; int rightLength = rhsLiteral.Arguments.Length; var typesWithAnnotationsBuilder = ArrayBuilder.GetInstance(leftLength); - var locationsBuilder = ArrayBuilder.GetInstance(leftLength); + var locationsBuilder = ArrayBuilder.GetInstance(leftLength); for (int i = 0; i < rightLength; i++) { BoundExpression element = rhsLiteral.Arguments[i]; - TypeSymbol mergedType = element.Type; + TypeSymbol? mergedType = element.Type; if (i < leftLength) { var variable = lhsVariables[i]; - if (variable.HasNestedVariables) + if (variable.NestedVariables is object) { if (element.Kind == BoundKind.TupleLiteral) { // (variables) on the left and (elements) on the right mergedType = MakeMergedTupleType(variable.NestedVariables, (BoundTupleLiteral)element, syntax, compilation, diagnostics); } - else if ((object)mergedType == null) + else if ((object?)mergedType == null && diagnostics is object) { // (variables) on the left and null on the right Error(diagnostics, ErrorCode.ERR_DeconstructRequiresExpression, element.Syntax); @@ -489,7 +491,8 @@ private static TypeSymbol MakeMergedTupleType(ArrayBuilder), + elementNames: default(ImmutableArray), compilation: compilation, diagnostics: diagnostics, shouldCheckConstraints: true, @@ -538,19 +541,20 @@ private static TypeSymbol MakeMergedTupleType(ArrayBuilder.GetInstance(count); var typesWithAnnotationsBuilder = ArrayBuilder.GetInstance(count); - var locationsBuilder = ArrayBuilder.GetInstance(count); - var namesBuilder = ArrayBuilder.GetInstance(count); + var locationsBuilder = ArrayBuilder.GetInstance(count); + var namesBuilder = ArrayBuilder.GetInstance(count); foreach (var variable in variables) { BoundExpression value; - if (variable.HasNestedVariables) + if (variable.NestedVariables is object) { value = DeconstructionVariablesAsTuple(variable.Syntax, variable.NestedVariables, diagnostics, ignoreDiagnosticsFromTuple); namesBuilder.Add(null); } else { + Debug.Assert(variable.Single is object); value = variable.Single; namesBuilder.Add(ExtractDeconstructResultElementName(value)); } @@ -564,7 +568,7 @@ private static TypeSymbol MakeMergedTupleType(ArrayBuilder tupleNames = namesBuilder is null ? default : namesBuilder.ToImmutableAndFree(); + ImmutableArray tupleNames = namesBuilder is null ? default : namesBuilder.ToImmutableAndFree(); ImmutableArray inferredPositions = tupleNames.IsDefault ? default : tupleNames.SelectAsArray(n => n != null); bool disallowInferredNames = this.Compilation.LanguageVersion.DisallowInferredTupleElementNames(); @@ -581,7 +585,7 @@ private static TypeSymbol MakeMergedTupleType(ArrayBuilderExtract inferred name from a single deconstruction variable. - private static string ExtractDeconstructResultElementName(BoundExpression expression) + private static string? ExtractDeconstructResultElementName(BoundExpression expression) { if (expression.Kind == BoundKind.DiscardExpression) { @@ -607,7 +611,7 @@ private static string ExtractDeconstructResultElementName(BoundExpression expres { anyApplicableCandidates = false; var receiverSyntax = (CSharpSyntaxNode)receiver.Syntax; - if (receiver.Type.IsDynamic()) + if (receiver.Type?.IsDynamic() ?? false) { Error(diagnostics, ErrorCode.ERR_CannotDeconstructDynamic, rightSyntax); outPlaceholders = default(ImmutableArray); @@ -695,9 +699,9 @@ private static string ExtractDeconstructResultElementName(BoundExpression expres private BoundBadExpression MissingDeconstruct(BoundExpression receiver, SyntaxNode rightSyntax, int numParameters, DiagnosticBag diagnostics, out ImmutableArray outPlaceholders, BoundExpression childNode) { - if (!receiver.Type.IsErrorType()) + if (receiver.Type?.IsErrorType() == false) { - Error(diagnostics, ErrorCode.ERR_MissingDeconstruct, rightSyntax, receiver.Type, numParameters); + Error(diagnostics, ErrorCode.ERR_MissingDeconstruct, rightSyntax, receiver.Type!, numParameters); } outPlaceholders = default; @@ -713,8 +717,8 @@ private static string ExtractDeconstructResultElementName(BoundExpression expres private DeconstructionVariable BindDeconstructionVariables( ExpressionSyntax node, DiagnosticBag diagnostics, - ref DeclarationExpressionSyntax declaration, - ref ExpressionSyntax expression) + ref DeclarationExpressionSyntax? declaration, + ref ExpressionSyntax? expression) { switch (node.Kind()) { diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Flags.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Flags.cs index 7374ede9d1163aa615c7e09587e42e1dd485dff9..6e8924be1ba73383ddd0906834f554ec8fbf5fa8 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Flags.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Flags.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using Microsoft.CodeAnalysis.CSharp.Symbols; using System.Diagnostics; diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Initializers.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Initializers.cs index 60fb9fb92dc3a7404a837ddc2051f14ab08e3e80..b6a3de92ecb469add88b7c983283f651c86cedc4 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Initializers.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Initializers.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Collections.Immutable; using System.Diagnostics; @@ -18,7 +19,7 @@ internal struct ProcessedFieldInitializers internal ImmutableArray BoundInitializers { get; set; } internal BoundStatement LoweredInitializers { get; set; } internal bool HasErrors { get; set; } - internal ImportChain FirstImportChain { get; set; } + internal ImportChain? FirstImportChain { get; set; } } internal static void BindFieldInitializers( @@ -29,7 +30,7 @@ internal struct ProcessedFieldInitializers ref ProcessedFieldInitializers processedInitializers) { var diagsForInstanceInitializers = DiagnosticBag.GetInstance(); - ImportChain firstImportChain; + ImportChain? firstImportChain; processedInitializers.BoundInitializers = BindFieldInitializers(compilation, scriptInitializerOpt, fieldInitializers, diagsForInstanceInitializers, out firstImportChain); processedInitializers.HasErrors = diagsForInstanceInitializers.HasAnyErrors(); processedInitializers.FirstImportChain = firstImportChain; @@ -42,7 +43,7 @@ internal struct ProcessedFieldInitializers SynthesizedInteractiveInitializerMethod scriptInitializerOpt, ImmutableArray> initializers, DiagnosticBag diagnostics, - out ImportChain firstImportChain) + out ImportChain? firstImportChain) { if (initializers.IsEmpty) { @@ -71,7 +72,7 @@ internal struct ProcessedFieldInitializers ImmutableArray> initializers, ArrayBuilder boundInitializers, DiagnosticBag diagnostics, - out ImportChain firstDebugImports) + out ImportChain? firstDebugImports) { firstDebugImports = null; @@ -80,7 +81,7 @@ internal struct ProcessedFieldInitializers // All sibling initializers share the same parent node and tree so we can reuse the binder // factory across siblings. Unfortunately, we cannot reuse the binder itself, because // individual fields might have their own binders (e.g. because of being declared unsafe). - BinderFactory binderFactory = null; + BinderFactory? binderFactory = null; foreach (FieldOrPropertyInitializer initializer in siblingInitializers) { @@ -129,7 +130,7 @@ internal struct ProcessedFieldInitializers ImmutableArray> initializers, ArrayBuilder boundInitializers, DiagnosticBag diagnostics, - out ImportChain firstDebugImports) + out ImportChain? firstDebugImports) { firstDebugImports = null; @@ -140,9 +141,9 @@ internal struct ProcessedFieldInitializers // All sibling initializers share the same parent node and tree so we can reuse the binder // factory across siblings. Unfortunately, we cannot reuse the binder itself, because // individual fields might have their own binders (e.g. because of being declared unsafe). - BinderFactory binderFactory = null; + BinderFactory? binderFactory = null; // Label instances must be shared across all global statements. - ScriptLocalScopeBinder.Labels labels = null; + ScriptLocalScopeBinder.Labels? labels = null; for (int j = 0; j < siblingInitializers.Length; j++) { @@ -169,7 +170,7 @@ internal struct ProcessedFieldInitializers } Binder scriptClassBinder = binderFactory.GetBinder(syntax); - Debug.Assert(((NamedTypeSymbol)scriptClassBinder.ContainingMemberOrLambda).IsScriptClass); + Debug.Assert(scriptClassBinder.ContainingMemberOrLambda is NamedTypeSymbol { IsScriptClass: true }); if (firstDebugImports == null) { @@ -182,7 +183,7 @@ internal struct ProcessedFieldInitializers new ScriptLocalScopeBinder(labels, scriptClassBinder)); BoundInitializer boundInitializer; - if ((object)fieldSymbol != null) + if ((object?)fieldSymbol != null) { boundInitializer = BindFieldInitializer( parentBinder.WithAdditionalFlagsAndContainingMemberOrLambda(BinderFlags.FieldInitializer, fieldSymbol), @@ -221,7 +222,7 @@ internal struct ProcessedFieldInitializers // insert an implicit conversion for the submission return type (if needed): var expression = InitializerRewriter.GetTrailingScriptExpression(statement); if (expression != null && - ((object)expression.Type == null || !expression.Type.IsVoidType())) + ((object?)expression.Type == null || !expression.Type.IsVoidType())) { var submissionResultType = scriptInitializer.ResultType; expression = binder.GenerateConversionForAssignment(submissionResultType, expression, diagnostics); @@ -256,7 +257,7 @@ internal struct ProcessedFieldInitializers var fieldsBeingBound = binder.FieldsBeingBound; var sourceField = fieldSymbol as SourceMemberFieldSymbolFromDeclarator; - bool isImplicitlyTypedField = (object)sourceField != null && sourceField.FieldTypeInferred(fieldsBeingBound); + bool isImplicitlyTypedField = (object?)sourceField != null && sourceField.FieldTypeInferred(fieldsBeingBound); // If the type is implicitly typed, the initializer diagnostics have already been reported, so ignore them here: // CONSIDER (tomat): reusing the bound field initializers for implicitly typed fields. diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_InterpolatedString.cs b/src/Compilers/CSharp/Portable/Binder/Binder_InterpolatedString.cs index 772aa24f760d766b5e257c9e305addd64db4803d..07ae7a62f983597eb2a0889382b26922db7ae362 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_InterpolatedString.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_InterpolatedString.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Collections.Generic; @@ -47,8 +48,8 @@ private BoundExpression BindInterpolatedString(InterpolatedStringExpressionSynta // GenerateConversionForAssignment with objectType. However we want to preserve the original expression's // natural type so that overload resolution may select a specialized implementation of string.Format, // so we discard the result of that call and only preserve its diagnostics. - BoundExpression alignment = null; - BoundLiteral format = null; + BoundExpression? alignment = null; + BoundLiteral? format = null; if (interpolation.AlignmentClause != null) { alignment = GenerateConversionForAssignment(intType, BindValue(interpolation.AlignmentClause.Value, diagnostics, Binder.BindValueKind.RValue), diagnostics); diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Lambda.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Lambda.cs index 8fda3cd10a51e9e362dfffb0781726451331f8cb..6023e0f289881ba7665af261245e55c5c1bb34d8 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Lambda.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Lambda.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Collections.Immutable; @@ -75,7 +76,7 @@ internal partial class Binder hasSignature = anon.ParameterList != null; if (hasSignature) { - parameterSyntaxList = anon.ParameterList.Parameters; + parameterSyntaxList = anon.ParameterList!.Parameters; } isAsync = (anon.AsyncKeyword.Kind() == SyntaxKind.AsyncKeyword); break; diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_NameConflicts.cs b/src/Compilers/CSharp/Portable/Binder/Binder_NameConflicts.cs index b6d1cf8f88ce1a61e001a68975311fd34ef4b596..e8d83a4c7fb3f780801d5c19a0d003b09d2ecb66 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_NameConflicts.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_NameConflicts.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Collections.Immutable; using Microsoft.CodeAnalysis.CSharp.Symbols; @@ -33,7 +34,7 @@ private static Location GetLocation(Symbol symbol) bool allowShadowingNames, DiagnosticBag diagnostics) { - PooledHashSet tpNames = null; + PooledHashSet? tpNames = null; if (!typeParameters.IsDefaultOrEmpty) { tpNames = PooledHashSet.GetInstance(); @@ -56,7 +57,7 @@ private static Location GetLocation(Symbol symbol) } } - PooledHashSet pNames = null; + PooledHashSet? pNames = null; if (!parameters.IsDefaultOrEmpty) { pNames = PooledHashSet.GetInstance(); @@ -93,7 +94,7 @@ private static Location GetLocation(Symbol symbol) /// /// Don't call this one directly - call one of the helpers. /// - private bool ValidateNameConflictsInScope(Symbol symbol, Location location, string name, DiagnosticBag diagnostics) + private bool ValidateNameConflictsInScope(Symbol? symbol, Location location, string name, DiagnosticBag diagnostics) { if (string.IsNullOrEmpty(name)) { @@ -102,7 +103,7 @@ private bool ValidateNameConflictsInScope(Symbol symbol, Location location, stri bool allowShadowing = Compilation.IsFeatureEnabled(MessageID.IDS_FeatureNameShadowingInNestedFunctions); - for (Binder binder = this; binder != null; binder = binder.Next) + for (Binder? binder = this; binder != null; binder = binder.Next) { // no local scopes enclose members if (binder is InContainerBinder) diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Query.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Query.cs index e0dd1a5ad06e347faddfed4494a78cf9f221af15..6db3b20772c6a05b308a5db50a4079fef4289ba2 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Query.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Query.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Collections.Generic; using System.Collections.Immutable; @@ -53,7 +54,7 @@ internal BoundExpression BindQuery(QueryExpressionSyntax node, DiagnosticBag dia // from T x in e // is translated into // from x in ( e ) . Cast < T > ( ) - BoundExpression cast = null; + BoundExpression? cast = null; if (fromClause.Type != null) { var typeRestriction = BindTypeArgument(fromClause.Type, diagnostics); @@ -63,7 +64,7 @@ internal BoundExpression BindQuery(QueryExpressionSyntax node, DiagnosticBag dia state.fromExpression = MakeQueryClause(fromClause, state.fromExpression, x, castInvocation: cast); BoundExpression result = BindQueryInternal1(state, diagnostics); - for (QueryContinuationSyntax continuation = node.Body.Continuation; continuation != null; continuation = continuation.Body.Continuation) + for (QueryContinuationSyntax? continuation = node.Body.Continuation; continuation != null; continuation = continuation.Body.Continuation) { // A query expression with a continuation // from ... into x ... @@ -129,7 +130,7 @@ private BoundExpression BindQueryInternal2(QueryTranslationState state, Diagnost // ignore missing or malformed Select method DiagnosticBag discarded = DiagnosticBag.GetInstance(); - var unoptimized = FinalTranslation(state, discarded); + BoundExpression? unoptimized = FinalTranslation(state, discarded); discarded.Free(); if (unoptimized.HasAnyErrors && !result.HasAnyErrors) unoptimized = null; @@ -186,7 +187,7 @@ private BoundExpression FinalTranslation(QueryTranslationState state, Diagnostic // k and v appear reversed in the invocation, so we reorder their evaluation result = ReverseLastTwoParameterOrder(result); - BoundExpression unoptimizedForm = null; + BoundExpression? unoptimizedForm = null; if (vId != null && vId.Identifier.ValueText == x.Name) { // The optimized form. We store the unoptimized form for analysis @@ -284,7 +285,7 @@ private void ReduceJoin(JoinClauseSyntax join, QueryTranslationState state, Diag inExpression = BadExpression(join.InExpression, inExpression); } - BoundExpression castInvocation = null; + BoundExpression? castInvocation = null; if (join.Type != null) { // A join clause that explicitly specifies a range variable type @@ -474,7 +475,7 @@ private void ReduceFrom(FromClauseSyntax from, QueryTranslationState state, Diag diagnostics); // Adjust the second-to-last parameter to be a query clause (if it was an extension method, an extra parameter was added) - BoundExpression castInvocation = (from.Type != null) ? ExtractCastInvocation(invocation) : null; + BoundExpression? castInvocation = (from.Type != null) ? ExtractCastInvocation(invocation) : null; var arguments = invocation.Arguments; invocation = invocation.Update( @@ -512,12 +513,12 @@ private void ReduceFrom(FromClauseSyntax from, QueryTranslationState state, Diag ImmutableArray.Create(collectionSelectorLambda, resultSelectorLambda), diagnostics); - BoundExpression castInvocation = (from.Type != null) ? ExtractCastInvocation(invocation) : null; + BoundExpression? castInvocation = (from.Type != null) ? ExtractCastInvocation(invocation) : null; state.fromExpression = MakeQueryClause(from, invocation, x2, invocation, castInvocation); } } - private static BoundExpression ExtractCastInvocation(BoundCall invocation) + private static BoundExpression? ExtractCastInvocation(BoundCall invocation) { int index = invocation.InvokedAsExtensionMethod ? 1 : 0; var c1 = invocation.Arguments[index] as BoundConversion; @@ -569,8 +570,7 @@ private void ReduceLet(LetClauseSyntax let, QueryTranslationState state, Diagnos { var xExpression = new BoundParameter(let, lambdaSymbol.Parameters[0]) { WasCompilerGenerated = true }; - lambdaBodyBinder = lambdaBodyBinder.GetBinder(let.Expression); - Debug.Assert(lambdaBodyBinder != null); + lambdaBodyBinder = lambdaBodyBinder.GetRequiredBinder(let.Expression); var yExpression = lambdaBodyBinder.BindRValueWithoutTargetType(let.Expression, d); SourceLocation errorLocation = new SourceLocation(let.SyntaxTree, new TextSpan(let.Identifier.SpanStart, let.Expression.Span.End - let.Identifier.SpanStart)); @@ -579,9 +579,9 @@ private void ReduceLet(LetClauseSyntax let, QueryTranslationState state, Diagnos Error(d, ErrorCode.ERR_QueryRangeVariableAssignedBadValue, errorLocation, yExpression.Display); yExpression = new BoundBadExpression(yExpression.Syntax, LookupResultKind.Empty, ImmutableArray.Empty, ImmutableArray.Create(yExpression), CreateErrorType()); } - else if (!yExpression.HasAnyErrors && yExpression.Type.IsVoidType()) + else if (!yExpression.HasAnyErrors && yExpression.Type!.IsVoidType()) { - Error(d, ErrorCode.ERR_QueryRangeVariableAssignedBadValue, errorLocation, yExpression.Type); + Error(d, ErrorCode.ERR_QueryRangeVariableAssignedBadValue, errorLocation, yExpression.Type!); yExpression = new BoundBadExpression(yExpression.Syntax, LookupResultKind.Empty, ImmutableArray.Empty, ImmutableArray.Create(yExpression), yExpression.Type); } @@ -615,10 +615,10 @@ private BoundBlock CreateLambdaBlockForQueryClause(ExpressionSyntax expression, private BoundQueryClause MakeQueryClause( CSharpSyntaxNode syntax, BoundExpression expression, - RangeVariableSymbol definedSymbol = null, - BoundExpression queryInvocation = null, - BoundExpression castInvocation = null, - BoundExpression unoptimizedForm = null) + RangeVariableSymbol? definedSymbol = null, + BoundExpression? queryInvocation = null, + BoundExpression? castInvocation = null, + BoundExpression? unoptimizedForm = null) { if (unoptimizedForm != null && unoptimizedForm.HasAnyErrors && !expression.HasAnyErrors) unoptimizedForm = null; return new BoundQueryClause( @@ -636,7 +636,7 @@ private BoundExpression MakePair(CSharpSyntaxNode node, string field1Name, Bound { // we will generate a diagnostic elsewhere field2Name = state.TransparentRangeVariableName(); - field2Value = new BoundBadExpression(field2Value.Syntax, LookupResultKind.Empty, ImmutableArray.Empty, ImmutableArray.Create(field2Value), field2Value.Type, true); + field2Value = new BoundBadExpression(field2Value.Syntax, LookupResultKind.Empty, ImmutableArray.Empty, ImmutableArray.Create(field2Value), field2Value.Type, true); } AnonymousTypeDescriptor typeDescriptor = new AnonymousTypeDescriptor( @@ -668,7 +668,7 @@ private UnboundLambda MakeQueryUnboundLambda(RangeVariableMap qvm, ImmutableArra { return MakeQueryUnboundLambda(expression, new QueryUnboundLambdaState(this, qvm, parameters, (LambdaSymbol lambdaSymbol, Binder lambdaBodyBinder, DiagnosticBag diagnostics) => { - lambdaBodyBinder = lambdaBodyBinder.GetBinder(expression); + lambdaBodyBinder = lambdaBodyBinder.GetRequiredBinder(expression); Debug.Assert(lambdaSymbol != null); BoundExpression boundExpression = lambdaBodyBinder.BindValue(expression, diagnostics, BindValueKind.RValue); return lambdaBodyBinder.CreateLambdaBlockForQueryClause(expression, boundExpression, diagnostics); @@ -679,8 +679,7 @@ private UnboundLambda MakeQueryUnboundLambdaWithCast(RangeVariableMap qvm, Range { return MakeQueryUnboundLambda(expression, new QueryUnboundLambdaState(this, qvm, ImmutableArray.Create(parameter), (LambdaSymbol lambdaSymbol, Binder lambdaBodyBinder, DiagnosticBag diagnostics) => { - lambdaBodyBinder = lambdaBodyBinder.GetBinder(expression); - Debug.Assert(lambdaBodyBinder != null); + lambdaBodyBinder = lambdaBodyBinder.GetRequiredBinder(expression); BoundExpression boundExpression = lambdaBodyBinder.BindValue(expression, diagnostics, BindValueKind.RValue); // We transform the expression from "expr" to "expr.Cast()". @@ -723,7 +722,8 @@ protected BoundCall MakeQueryInvocation(CSharpSyntaxNode node, BoundExpression r // clean up the receiver var ultimateReceiver = receiver; while (ultimateReceiver.Kind == BoundKind.QueryClause) ultimateReceiver = ((BoundQueryClause)ultimateReceiver).Value; - if ((object)ultimateReceiver.Type == null) + Debug.Assert(receiver.Type is object || ultimateReceiver.Type is null); + if ((object?)ultimateReceiver.Type == null) { if (ultimateReceiver.HasAnyErrors || node.HasErrors) { @@ -749,7 +749,7 @@ protected BoundCall MakeQueryInvocation(CSharpSyntaxNode node, BoundExpression r else if (ultimateReceiver.Kind == BoundKind.MethodGroup) { var methodGroup = (BoundMethodGroup)ultimateReceiver; - HashSet useSiteDiagnostics = null; + HashSet? useSiteDiagnostics = null; var resolution = this.ResolveMethodGroup(methodGroup, analyzedArguments: null, isMethodGroupConversion: false, useSiteDiagnostics: ref useSiteDiagnostics); diagnostics.Add(node, useSiteDiagnostics); diagnostics.AddRange(resolution.Diagnostics); @@ -767,7 +767,7 @@ protected BoundCall MakeQueryInvocation(CSharpSyntaxNode node, BoundExpression r receiver = new BoundBadExpression(receiver.Syntax, LookupResultKind.NotAValue, ImmutableArray.Empty, ImmutableArray.Create(receiver), CreateErrorType()); } - else if (receiver.Type.IsVoidType()) + else if (receiver.Type!.IsVoidType()) { if (!receiver.HasAnyErrors && !node.HasErrors) { diff --git a/src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml b/src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml index 451a9f8ea97447961c00458d58715527cac61805..1a2e91b85332db11962b1a6cde7197ebb484a9d2 100644 --- a/src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml +++ b/src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml @@ -1576,7 +1576,7 @@ - + diff --git a/src/Compilers/CSharp/Portable/Generated/BoundNodes.xml.Generated.cs b/src/Compilers/CSharp/Portable/Generated/BoundNodes.xml.Generated.cs index 62408fe4ec778dbd2ffe920e9b5ce3aa847e4c73..1a3b7f1f2180a3919aa0dcfbe58194d1710aefcb 100644 --- a/src/Compilers/CSharp/Portable/Generated/BoundNodes.xml.Generated.cs +++ b/src/Compilers/CSharp/Portable/Generated/BoundNodes.xml.Generated.cs @@ -5542,7 +5542,7 @@ public BoundObjectCreationExpression Update(MethodSymbol constructor, ImmutableA internal abstract partial class BoundTupleExpression : BoundExpression { - protected BoundTupleExpression(BoundKind kind, SyntaxNode syntax, ImmutableArray arguments, ImmutableArray argumentNamesOpt, ImmutableArray inferredNamesOpt, TypeSymbol? type, bool hasErrors = false) + protected BoundTupleExpression(BoundKind kind, SyntaxNode syntax, ImmutableArray arguments, ImmutableArray argumentNamesOpt, ImmutableArray inferredNamesOpt, TypeSymbol? type, bool hasErrors = false) : base(kind, syntax, type, hasErrors) { @@ -5556,14 +5556,14 @@ protected BoundTupleExpression(BoundKind kind, SyntaxNode syntax, ImmutableArray public ImmutableArray Arguments { get; } - public ImmutableArray ArgumentNamesOpt { get; } + public ImmutableArray ArgumentNamesOpt { get; } public ImmutableArray InferredNamesOpt { get; } } internal sealed partial class BoundTupleLiteral : BoundTupleExpression { - public BoundTupleLiteral(SyntaxNode syntax, ImmutableArray arguments, ImmutableArray argumentNamesOpt, ImmutableArray inferredNamesOpt, TypeSymbol? type, bool hasErrors = false) + public BoundTupleLiteral(SyntaxNode syntax, ImmutableArray arguments, ImmutableArray argumentNamesOpt, ImmutableArray inferredNamesOpt, TypeSymbol? type, bool hasErrors = false) : base(BoundKind.TupleLiteral, syntax, arguments, argumentNamesOpt, inferredNamesOpt, type, hasErrors || arguments.HasErrors()) { @@ -5576,7 +5576,7 @@ public BoundTupleLiteral(SyntaxNode syntax, ImmutableArray argu [DebuggerStepThrough] public override BoundNode? Accept(BoundTreeVisitor visitor) => visitor.VisitTupleLiteral(this); - public BoundTupleLiteral Update(ImmutableArray arguments, ImmutableArray argumentNamesOpt, ImmutableArray inferredNamesOpt, TypeSymbol? type) + public BoundTupleLiteral Update(ImmutableArray arguments, ImmutableArray argumentNamesOpt, ImmutableArray inferredNamesOpt, TypeSymbol? type) { if (arguments != this.Arguments || argumentNamesOpt != this.ArgumentNamesOpt || inferredNamesOpt != this.InferredNamesOpt || !TypeSymbol.Equals(type, this.Type, TypeCompareKind.ConsiderEverything)) { @@ -5590,7 +5590,7 @@ public BoundTupleLiteral Update(ImmutableArray arguments, Immut internal sealed partial class BoundConvertedTupleLiteral : BoundTupleExpression { - public BoundConvertedTupleLiteral(SyntaxNode syntax, BoundTupleLiteral? sourceTuple, bool wasTargetTyped, ImmutableArray arguments, ImmutableArray argumentNamesOpt, ImmutableArray inferredNamesOpt, TypeSymbol? type, bool hasErrors = false) + public BoundConvertedTupleLiteral(SyntaxNode syntax, BoundTupleLiteral? sourceTuple, bool wasTargetTyped, ImmutableArray arguments, ImmutableArray argumentNamesOpt, ImmutableArray inferredNamesOpt, TypeSymbol? type, bool hasErrors = false) : base(BoundKind.ConvertedTupleLiteral, syntax, arguments, argumentNamesOpt, inferredNamesOpt, type, hasErrors || sourceTuple.HasErrors() || arguments.HasErrors()) { @@ -5607,7 +5607,7 @@ public BoundConvertedTupleLiteral(SyntaxNode syntax, BoundTupleLiteral? sourceTu [DebuggerStepThrough] public override BoundNode? Accept(BoundTreeVisitor visitor) => visitor.VisitConvertedTupleLiteral(this); - public BoundConvertedTupleLiteral Update(BoundTupleLiteral? sourceTuple, bool wasTargetTyped, ImmutableArray arguments, ImmutableArray argumentNamesOpt, ImmutableArray inferredNamesOpt, TypeSymbol? type) + public BoundConvertedTupleLiteral Update(BoundTupleLiteral? sourceTuple, bool wasTargetTyped, ImmutableArray arguments, ImmutableArray argumentNamesOpt, ImmutableArray inferredNamesOpt, TypeSymbol? type) { if (sourceTuple != this.SourceTuple || wasTargetTyped != this.WasTargetTyped || arguments != this.Arguments || argumentNamesOpt != this.ArgumentNamesOpt || inferredNamesOpt != this.InferredNamesOpt || !TypeSymbol.Equals(type, this.Type, TypeCompareKind.ConsiderEverything)) { diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_DeconstructionAssignmentOperator.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_DeconstructionAssignmentOperator.cs index 048a752ef9b2843647d0f8150f821ccd1c5cdffd..27e4e28b3dc4a8f2e1565dc375a923e5ea22bf83 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_DeconstructionAssignmentOperator.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_DeconstructionAssignmentOperator.cs @@ -129,7 +129,7 @@ private BoundExpression RewriteDeconstruction(BoundTupleExpression left, Convers for (int i = 0; i < leftTargets.Count; i++) { BoundExpression resultPart; - if (leftTargets[i].HasNestedVariables) + if (leftTargets[i].NestedVariables is object) { resultPart = ApplyDeconstructionConversion(leftTargets[i].NestedVariables, rightParts[i], underlyingConversions[i], temps, effects, isUsed, inInit);