diff --git a/docs/features/nullable-reference-types.md b/docs/features/nullable-reference-types.md index 007323a325849..933fb679bdc81 100644 --- a/docs/features/nullable-reference-types.md +++ b/docs/features/nullable-reference-types.md @@ -175,6 +175,13 @@ A `class?` constraint is allowed, which, like class, requires the type argument [Nullable strawman](https://github.com/dotnet/csharplang/issues/790) [4/25/18](https://github.com/dotnet/csharplang/blob/master/meetings/2018/LDM-2018-04-25.md) +An explicit `object` (or `System.Object`) constraint is allowed, which requires the type to be non-nullable when it is a reference type. +However, an explicit `object?` constraint is not allowed. +An unconstrained type parameter is essentially equivalent to one constrained by `object?`. +[4/25/18](https://github.com/dotnet/csharplang/blob/master/meetings/2018/LDM-2018-04-25.md) +Note, the `object`/`System.Object` constraint is represented in metadata as any other type constraint, the type is System.Object. + + A warning is reported for nullable type argument for type parameter with `class` constraint or non-nullable reference type or interface type constraint. [4/25/18](https://github.com/dotnet/csharplang/blob/master/meetings/2018/LDM-2018-04-25.md) ```c# diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Constraints.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Constraints.cs index b8503ecd6fef3..70847b2a115d5 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Constraints.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Constraints.cs @@ -103,6 +103,7 @@ private TypeParameterConstraintClause BindTypeParameterConstraints( var constraintTypes = ArrayBuilder.GetInstance(); var syntaxBuilder = ArrayBuilder.GetInstance(); SeparatedSyntaxList constraintsSyntax = constraintClauseSyntax.Constraints; + Debug.Assert(!InExecutableBinder); // Cannot eagerly report diagnostics handled by LazyMissingNonNullTypesContextDiagnosticInfo for (int i = 0, n = constraintsSyntax.Count; i < n; i++) { @@ -115,9 +116,11 @@ private TypeParameterConstraintClause BindTypeParameterConstraints( diagnostics.Add(ErrorCode.ERR_RefValBoundMustBeFirst, syntax.GetFirstToken().GetLocation()); } - if (((ClassOrStructConstraintSyntax)syntax).QuestionToken.IsKind(SyntaxKind.QuestionToken)) + SyntaxToken questionToken = ((ClassOrStructConstraintSyntax)syntax).QuestionToken; + if (questionToken.IsKind(SyntaxKind.QuestionToken)) { constraints |= TypeParameterConstraintKind.NullableReferenceType; + diagnostics.Add(new LazyMissingNonNullTypesContextDiagnosticInfo(Compilation, NonNullTypesContext, type: default), questionToken.GetLocation()); } else { @@ -198,7 +201,7 @@ private TypeParameterConstraintClause BindTypeParameterConstraints( } } - return TypeParameterConstraintClause.Create(constraints, constraintTypes.ToImmutableAndFree(), constraintClauseSyntax, syntaxBuilder.ToImmutableAndFree()); + return TypeParameterConstraintClause.Create(constraints, constraintTypes.ToImmutableAndFree(), syntaxBuilder.ToImmutableAndFree()); } /// @@ -213,7 +216,7 @@ internal static bool IsValidConstraint( ArrayBuilder constraintTypes, DiagnosticBag diagnostics) { - if (!IsValidConstraintType(syntax, type.TypeSymbol, diagnostics)) + if (!IsValidConstraintType(syntax, type, diagnostics)) { return false; } @@ -278,8 +281,10 @@ internal static bool IsValidConstraint( /// Returns true if the type is a valid constraint type. /// Otherwise returns false and generates a diagnostic. /// - private static bool IsValidConstraintType(TypeConstraintSyntax syntax, TypeSymbol type, DiagnosticBag diagnostics) + private static bool IsValidConstraintType(TypeConstraintSyntax syntax, TypeSymbolWithAnnotations typeWithAnnotations, DiagnosticBag diagnostics) { + TypeSymbol type = typeWithAnnotations.TypeSymbol; + switch (type.SpecialType) { case SpecialType.System_Enum: @@ -292,6 +297,16 @@ private static bool IsValidConstraintType(TypeConstraintSyntax syntax, TypeSymbo break; case SpecialType.System_Object: + if (typeWithAnnotations.IsAnnotated) + { + // "Constraint cannot be special class '{0}'" + Error(diagnostics, ErrorCode.ERR_SpecialTypeAsBound, syntax, typeWithAnnotations); + return false; + } + + CheckFeatureAvailability(syntax, MessageID.IDS_FeatureObjectGenericTypeConstraint, diagnostics); + break; + case SpecialType.System_ValueType: case SpecialType.System_Array: // "Constraint cannot be special class '{0}'" diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs index 4ac604daeabc5..e8d99dae2e47b 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs @@ -343,20 +343,7 @@ internal NamespaceOrTypeOrAliasSymbolWithAnnotations BindNamespaceOrTypeOrAliasS TypeSymbolWithAnnotations typeArgument = BindType(typeArgumentSyntax, diagnostics, basesBeingResolved); TypeSymbolWithAnnotations constructedType = typeArgument.SetIsAnnotated(Compilation); - if (InExecutableBinder) - { - // Inside a method body or other executable code, we can pull on NonNullTypes symbol or question IsValueType without causing cycles. - // Types created outside executable context should be checked by the responsible symbol (the method symbol checks its return type, for instance). - // We still need to delay that check when binding in an attribute argument - if (!ShouldCheckConstraintsNullability) - { - diagnostics.Add(new LazyMissingNonNullTypesContextDiagnosticInfo(Compilation, NonNullTypesContext, typeArgument), nullableSyntax.QuestionToken.GetLocation()); - } - else if (!typeArgument.IsValueType) - { - Symbol.ReportNullableReferenceTypesIfNeeded(Compilation, NonNullTypesContext, diagnostics, nullableSyntax.QuestionToken.GetLocation()); - } - } + reportNullableReferenceTypesIfNeeded(nullableSyntax.QuestionToken, typeArgument); if (!ShouldCheckConstraints) { @@ -375,6 +362,10 @@ internal NamespaceOrTypeOrAliasSymbolWithAnnotations BindNamespaceOrTypeOrAliasS } type.CheckConstraints(this.Compilation, conversions, location, diagnostics); } + else if (constructedType.TypeSymbol.IsUnconstrainedTypeParameter()) + { + diagnostics.Add(ErrorCode.ERR_NullableUnconstrainedTypeParameter, syntax.Location); + } return constructedType; } @@ -451,6 +442,7 @@ internal NamespaceOrTypeOrAliasSymbolWithAnnotations BindNamespaceOrTypeOrAliasS if (a.QuestionToken.IsKind(SyntaxKind.QuestionToken)) { type = TypeSymbolWithAnnotations.Create(array, isNullableIfReferenceType: true); + reportNullableReferenceTypesIfNeeded(a.QuestionToken); } else { @@ -508,6 +500,25 @@ internal NamespaceOrTypeOrAliasSymbolWithAnnotations BindNamespaceOrTypeOrAliasS default: throw ExceptionUtilities.UnexpectedValue(syntax.Kind()); } + + void reportNullableReferenceTypesIfNeeded(SyntaxToken questionToken, TypeSymbolWithAnnotations typeArgument = default) + { + // Inside a method body or other executable code, we can pull on NonNullTypes symbol or question IsValueType without causing cycles. + // We still need to delay that check when binding in an attribute argument + if (!InExecutableBinder || !ShouldCheckConstraintsNullability) + { + diagnostics.Add(new LazyMissingNonNullTypesContextDiagnosticInfo(Compilation, NonNullTypesContext, typeArgument), questionToken.GetLocation()); + } + else + { + DiagnosticInfo info = LazyMissingNonNullTypesContextDiagnosticInfo.ReportNullableReferenceTypesIfNeeded(Compilation, NonNullTypesContext, typeArgument); + + if (!(info is null)) + { + diagnostics.Add(info, questionToken.GetLocation()); + } + } + } } private TypeSymbol BindTupleType(TupleTypeSyntax syntax, DiagnosticBag diagnostics) diff --git a/src/Compilers/CSharp/Portable/BoundTree/UnboundLambda.cs b/src/Compilers/CSharp/Portable/BoundTree/UnboundLambda.cs index 56fb63c065e2a..ca5d7a3db5376 100644 --- a/src/Compilers/CSharp/Portable/BoundTree/UnboundLambda.cs +++ b/src/Compilers/CSharp/Portable/BoundTree/UnboundLambda.cs @@ -480,7 +480,6 @@ private BoundLambda ReallyBind(NamedTypeSymbol delegateType) if (!returnType.IsNull) { - returnType.ReportAnnotatedUnconstrainedTypeParameterIfAny(lambdaSymbol.DiagnosticLocation, diagnostics); if (returnType.ContainsNullableReferenceTypes()) { binder.Compilation.EnsureNullableAttributeExists(diagnostics, lambdaSymbol.DiagnosticLocation, modifyCompilation: false); @@ -488,7 +487,6 @@ private BoundLambda ReallyBind(NamedTypeSymbol delegateType) } } - ParameterHelpers.ReportAnnotatedUnconstrainedTypeParameters(lambdaParameters, diagnostics); ParameterHelpers.EnsureNullableAttributeExists(lambdaParameters, diagnostics, modifyCompilation: false); // Note: we don't need to warn on annotations used without NonNullTypes context for lambdas, as this is handled in binding already diff --git a/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs b/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs index 7596b46e49e3d..cd64b7bdbde8c 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs +++ b/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs @@ -10862,6 +10862,15 @@ internal static string IDS_FeatureNullPropagatingOperator { } } + /// + /// Looks up a localized string similar to object generic type constraint. + /// + internal static string IDS_FeatureObjectGenericTypeConstraint { + get { + return ResourceManager.GetString("IDS_FeatureObjectGenericTypeConstraint", resourceCulture); + } + } + /// /// Looks up a localized string similar to object initializer. /// diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx index 0cc05815833cc..d011530437b8b 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.resx +++ b/src/Compilers/CSharp/Portable/CSharpResources.resx @@ -5546,4 +5546,7 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ The type cannot be used as type parameter in the generic type or method. Nullability of type argument doesn't match 'class' constraint. + + object generic type constraint + diff --git a/src/Compilers/CSharp/Portable/Emitter/Model/TypeParameterSymbolAdapter.cs b/src/Compilers/CSharp/Portable/Emitter/Model/TypeParameterSymbolAdapter.cs index f591047da333f..d207692697ee7 100644 --- a/src/Compilers/CSharp/Portable/Emitter/Model/TypeParameterSymbolAdapter.cs +++ b/src/Compilers/CSharp/Portable/Emitter/Model/TypeParameterSymbolAdapter.cs @@ -247,8 +247,8 @@ Cci.ITypeReference Cci.IGenericTypeParameterReference.DefiningType switch (type.SpecialType) { case SpecialType.System_Object: - // Avoid emitting unnecessary object constraint. - continue; + Debug.Assert(!type.IsAnnotated); + break; case SpecialType.System_ValueType: seenValueType = true; break; diff --git a/src/Compilers/CSharp/Portable/Errors/LazyMissingNonNullTypesContextDiagnosticInfo.cs b/src/Compilers/CSharp/Portable/Errors/LazyMissingNonNullTypesContextDiagnosticInfo.cs index 16e13b3ccf6ad..ed23cb5f03356 100644 --- a/src/Compilers/CSharp/Portable/Errors/LazyMissingNonNullTypesContextDiagnosticInfo.cs +++ b/src/Compilers/CSharp/Portable/Errors/LazyMissingNonNullTypesContextDiagnosticInfo.cs @@ -22,7 +22,36 @@ internal LazyMissingNonNullTypesContextDiagnosticInfo(CSharpCompilation compilat protected override DiagnosticInfo ResolveInfo() { - return _type.IsValueType ? null : Symbol.ReportNullableReferenceTypesIfNeeded(_compilation, _context); + return ReportNullableReferenceTypesIfNeeded(_compilation, _context, _type); + } + + /// + /// A `?` annotation on a type that isn't a value type causes: + /// - an error before C# 8.0 + /// - a warning outside of a NonNullTypes context + /// + public static DiagnosticInfo ReportNullableReferenceTypesIfNeeded(CSharpCompilation compilation, INonNullTypesContext context, TypeSymbolWithAnnotations type) + { + return !type.IsNull && (type.IsValueType || type.IsErrorType()) ? null : ReportNullableReferenceTypesIfNeeded(compilation, context); + } + + private static DiagnosticInfo ReportNullableReferenceTypesIfNeeded(CSharpCompilation compilation, INonNullTypesContext nonNullTypesContext) + { + var featureID = MessageID.IDS_FeatureStaticNullChecking; + if (!compilation.IsFeatureEnabled(featureID)) + { + LanguageVersion availableVersion = compilation.LanguageVersion; + LanguageVersion requiredVersion = featureID.RequiredVersion(); + + return new CSDiagnosticInfo(availableVersion.GetErrorCode(), featureID.Localize(), new CSharpRequiredLanguageVersion(requiredVersion)); + } + else if (nonNullTypesContext.NonNullTypes != true) + { + return new CSDiagnosticInfo(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation); + } + + return null; } } } + diff --git a/src/Compilers/CSharp/Portable/Errors/LazyUseSiteDiagnosticsInfoForNullableType.cs b/src/Compilers/CSharp/Portable/Errors/LazyUseSiteDiagnosticsInfoForNullableType.cs index 20100fee9fc13..708675bf679d8 100644 --- a/src/Compilers/CSharp/Portable/Errors/LazyUseSiteDiagnosticsInfoForNullableType.cs +++ b/src/Compilers/CSharp/Portable/Errors/LazyUseSiteDiagnosticsInfoForNullableType.cs @@ -19,6 +19,10 @@ protected override DiagnosticInfo ResolveInfo() { return _possiblyNullableTypeSymbol.TypeSymbol.OriginalDefinition.GetUseSiteDiagnostic(); } + else if (_possiblyNullableTypeSymbol.TypeSymbol.IsUnconstrainedTypeParameter()) + { + return new CSDiagnosticInfo(ErrorCode.ERR_NullableUnconstrainedTypeParameter); + } return null; } diff --git a/src/Compilers/CSharp/Portable/Errors/MessageID.cs b/src/Compilers/CSharp/Portable/Errors/MessageID.cs index 5c18550281735..d3c106b27c2dd 100644 --- a/src/Compilers/CSharp/Portable/Errors/MessageID.cs +++ b/src/Compilers/CSharp/Portable/Errors/MessageID.cs @@ -163,6 +163,7 @@ internal enum MessageID IDS_FeatureIndexingMovableFixedBuffers = MessageBase + 12744, IDS_InjectedDeclaration = MessageBase + 12745, + IDS_FeatureObjectGenericTypeConstraint = MessageBase + 12746, } // Message IDs may refer to strings that need to be localized. @@ -204,6 +205,7 @@ internal static LanguageVersion RequiredVersion(this MessageID feature) { // C# 8 features. case MessageID.IDS_FeatureStaticNullChecking: // syntax and semantic check + case MessageID.IDS_FeatureObjectGenericTypeConstraint: // semantic check return LanguageVersion.CSharp8; // C# 7.3 features. diff --git a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs index f8976bf49e5b7..f8cebdf850736 100644 --- a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs +++ b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs @@ -6370,7 +6370,7 @@ private ArrayRankSpecifierSyntax ParseArrayRankSpecifier(bool isArrayCreation, b SyntaxToken questionToken = null; if (allowQuestionToken && this.CurrentToken.Kind == SyntaxKind.QuestionToken) { - questionToken = CheckFeatureAvailability(this.EatToken(), MessageID.IDS_FeatureStaticNullChecking); + questionToken = this.EatToken(); } return _syntaxFactory.ArrayRankSpecifier(open, list, close, questionToken); diff --git a/src/Compilers/CSharp/Portable/Symbols/ConstraintsHelper.cs b/src/Compilers/CSharp/Portable/Symbols/ConstraintsHelper.cs index f8136013655c0..ae31c874fef7c 100644 --- a/src/Compilers/CSharp/Portable/Symbols/ConstraintsHelper.cs +++ b/src/Compilers/CSharp/Portable/Symbols/ConstraintsHelper.cs @@ -396,25 +396,6 @@ private static TypeParameterConstraintClause MakeTypeParameterConstraintsLate( { Symbol containingSymbol = typeParameter.ContainingSymbol; - bool onLocalFunction = containingSymbol.Kind == SymbolKind.Method && ((MethodSymbol)containingSymbol).MethodKind == MethodKind.LocalFunction; - - if ((constraintClause.Constraints & TypeParameterConstraintKind.NullableReferenceType) == TypeParameterConstraintKind.NullableReferenceType) - { - Location location = constraintClause.ClauseSyntax.Location; - - foreach (TypeParameterConstraintSyntax constraintSyntax in constraintClause.ClauseSyntax.Constraints) - { - if (constraintSyntax.IsKind(SyntaxKind.ClassConstraint) && - ((ClassOrStructConstraintSyntax)constraintSyntax).QuestionToken.IsKind(SyntaxKind.QuestionToken)) - { - location = ((ClassOrStructConstraintSyntax)constraintSyntax).QuestionToken.GetLocation(); - break; - } - } - - typeParameter.ReportNullableReferenceTypesIfNeeded(diagnostics, location); - } - var constraintTypeBuilder = ArrayBuilder.GetInstance(); var constraintTypes = constraintClause.ConstraintTypes; int n = constraintTypes.Length; @@ -431,14 +412,6 @@ private static TypeParameterConstraintClause MakeTypeParameterConstraintsLate( containingSymbol.CheckConstraintTypeVisibility(syntax.Location, constraintType, diagnostics); constraintTypeBuilder.Add(constraintType); } - - constraintType.ReportAnnotatedUnconstrainedTypeParameterIfAny(syntax.Location, diagnostics); - - if (!onLocalFunction && constraintType.ContainsNullableReferenceTypes()) - { - // Note: Misuse of ? annotation on declarations of local functions is reported when binding their types (since in executable context) - typeParameter.ReportNullableReferenceTypesIfNeeded(diagnostics, syntax.Location); - } } if (constraintTypeBuilder.Count < n) @@ -966,7 +939,7 @@ private static bool CheckConstraints( { if (!SatisfiesConstraintType(conversions, typeArgument, constraintType, ref useSiteDiagnostics) || (typeArgument.IsNullable == true && !typeArgument.IsValueType && - TypeParameterSymbol.IsNotNullableIfReferenceTypeFromConstraintType(constraintType, ConsList.Empty) == true)) + TypeParameterSymbol.IsNotNullableIfReferenceTypeFromConstraintType(constraintType) == true)) { var diagnostic = new CSDiagnosticInfo(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, containingSymbol.ConstructedFrom(), constraintType, typeParameter, typeArgument); warningsBuilderOpt.Add(new TypeParameterDiagnosticInfo(typeParameter, diagnostic)); diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PETypeParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PETypeParameterSymbol.cs index 1f5fba38bf6a2..2db8ddfbe14ac 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PETypeParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PETypeParameterSymbol.cs @@ -206,15 +206,16 @@ private ImmutableArray GetDeclaredConstraintTypes() } } - // Drop 'System.Object' constraint type. - if (typeSymbol.SpecialType == SpecialType.System_Object) + // PROTOTYPE(NullableReferenceTypes): Test different [NonNullTypes] on method and containing type. + var type = TypeSymbolWithAnnotations.Create(this, typeSymbol); + type = NullableTypeDecoder.TransformType(type, constraintHandle, moduleSymbol); + + // Drop 'System.Object?' constraint type. + if (type.SpecialType == SpecialType.System_Object && type.IsAnnotated) { continue; } - // PROTOTYPE(NullableReferenceTypes): Test different [NonNullTypes] on method and containing type. - var type = TypeSymbolWithAnnotations.Create(this, typeSymbol); - type = NullableTypeDecoder.TransformType(type, constraintHandle, moduleSymbol); type = TupleTypeDecoder.DecodeTupleTypesIfApplicable(type, constraintHandle, moduleSymbol); symbolsBuilder.Add(type); diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/LocalFunctionSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/LocalFunctionSymbol.cs index 4df044a4b2b6b..86a8a573c5518 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/LocalFunctionSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/LocalFunctionSymbol.cs @@ -167,7 +167,6 @@ private void ComputeParameters() diagnostics: diagnostics); ParameterHelpers.EnsureIsReadOnlyAttributeExists(parameters, diagnostics, modifyCompilation: false); - ParameterHelpers.ReportAnnotatedUnconstrainedTypeParameters(parameters, diagnostics); ParameterHelpers.EnsureNullableAttributeExists(parameters, diagnostics, modifyCompilation: false); // Note: we don't need to warn on annotations used without NonNullTypes context for local functions, as this is handled in binding already @@ -232,7 +231,6 @@ internal void ComputeReturnType() DeclaringCompilation.EnsureIsReadOnlyAttributeExists(diagnostics, location, modifyCompilation: false); } - returnType.ReportAnnotatedUnconstrainedTypeParameterIfAny(location, diagnostics); if (returnType.ContainsNullableReferenceTypes()) { DeclaringCompilation.EnsureNullableAttributeExists(diagnostics, location, modifyCompilation: false); diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs b/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs index 1e64af9fad8fd..96df6d00dfde5 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs @@ -144,26 +144,6 @@ internal static void EnsureNullableAttributeExists(ImmutableArray parameters, DiagnosticBag diagnostics) - { - foreach (var parameter in parameters) - { - if (parameter.Type.ContainsNullableReferenceTypes()) - { - parameter.ReportNullableReferenceTypesIfNeeded(diagnostics, parameter.GetNonNullSyntaxNode().Location); - } - } - } - - internal static void ReportAnnotatedUnconstrainedTypeParameters(ImmutableArray parameters, DiagnosticBag diagnostics) - { - foreach (var parameter in parameters) - { - var location = parameter.GetNonNullSyntaxNode().Location; - parameter.Type.ReportAnnotatedUnconstrainedTypeParameterIfAny(location, diagnostics); - } - } - private static void CheckParameterModifiers( ParameterSyntax parameter, DiagnosticBag diagnostics) { diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceConstructorSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceConstructorSymbol.cs index db59aa11bbb94..9c2069d26799b 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceConstructorSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceConstructorSymbol.cs @@ -114,9 +114,7 @@ internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, base.AfterAddingTypeMembersChecks(conversions, diagnostics); ParameterHelpers.EnsureIsReadOnlyAttributeExists(Parameters, diagnostics, modifyCompilation: true); - ParameterHelpers.ReportAnnotatedUnconstrainedTypeParameters(Parameters, diagnostics); ParameterHelpers.EnsureNullableAttributeExists(Parameters, diagnostics, modifyCompilation: true); - ParameterHelpers.ReportNullableReferenceTypesIfNeeded(Parameters, diagnostics); } internal ConstructorDeclarationSyntax GetSyntax() diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceDelegateMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceDelegateMethodSymbol.cs index 752b3a96af451..4f1d38409a2fc 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceDelegateMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceDelegateMethodSymbol.cs @@ -317,16 +317,12 @@ internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, ParameterHelpers.EnsureIsReadOnlyAttributeExists(Parameters, diagnostics, modifyCompilation: true); - ReturnType.ReportAnnotatedUnconstrainedTypeParameterIfAny(location, diagnostics); if (ReturnType.ContainsNullableReferenceTypes()) { this.DeclaringCompilation.EnsureNullableAttributeExists(diagnostics, location, modifyCompilation: true); - ReportNullableReferenceTypesIfNeeded(diagnostics, location); } - ParameterHelpers.ReportAnnotatedUnconstrainedTypeParameters(Parameters, diagnostics); ParameterHelpers.EnsureNullableAttributeExists(Parameters, diagnostics, modifyCompilation: true); - ParameterHelpers.ReportNullableReferenceTypesIfNeeded(Parameters, diagnostics); } public override ImmutableArray RefCustomModifiers => _refCustomModifiers; diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventSymbol.cs index 2d4cb0d6a3e8a..b7dc9bf62d053 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventSymbol.cs @@ -687,11 +687,9 @@ internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, this.CheckModifiersAndType(diagnostics); this.Type.CheckAllConstraints(conversions, location, diagnostics); - this.Type.ReportAnnotatedUnconstrainedTypeParameterIfAny(location, diagnostics); if (this.Type.ContainsNullableReferenceTypes()) { this.DeclaringCompilation.EnsureNullableAttributeExists(diagnostics, location, modifyCompilation: true); - ReportNullableReferenceTypesIfNeeded(diagnostics, location); } } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldSymbol.cs index d02b4df387d9c..7e13447629903 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldSymbol.cs @@ -128,11 +128,9 @@ internal sealed override void DecodeWellKnownAttribute(ref DecodeWellKnownAttrib internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, DiagnosticBag diagnostics) { var location = ErrorLocation; - this.Type.ReportAnnotatedUnconstrainedTypeParameterIfAny(location, diagnostics); if (this.Type.ContainsNullableReferenceTypes()) { DeclaringCompilation.EnsureNullableAttributeExists(diagnostics, location, modifyCompilation: true); - ReportNullableReferenceTypesIfNeeded(diagnostics, location); } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs index a8d504804c51a..9c749748a9f70 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs @@ -1417,16 +1417,10 @@ protected void AfterMembersChecks(DiagnosticBag diagnostics) // PROTOTYPE(NullableReferenceTypes): Report diagnostics for base type and interfaces at more specific locations. var baseType = BaseTypeNoUseSiteDiagnostics; var interfaces = InterfacesNoUseSiteDiagnostics(); - if (baseType?.ContainsAnnotatedUnconstrainedTypeParameter() == true || - interfaces.Any(t => t.ContainsAnnotatedUnconstrainedTypeParameter())) - { - TypeSymbolWithAnnotations.ReportAnnotatedUnconstrainedTypeParameter(location, diagnostics); - } if (baseType?.ContainsNullableReferenceTypes() == true || interfaces.Any(t => t.ContainsNullableReferenceTypes())) { this.DeclaringCompilation.EnsureNullableAttributeExists(diagnostics, location, modifyCompilation: true); - ReportNullableReferenceTypesIfNeeded(diagnostics, location); } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodSymbol.cs index 279d5de02d005..bb45a7226ffdb 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodSymbol.cs @@ -1050,16 +1050,12 @@ internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, ParameterHelpers.EnsureIsReadOnlyAttributeExists(Parameters, diagnostics, modifyCompilation: true); - ReturnType.ReportAnnotatedUnconstrainedTypeParameterIfAny(location, diagnostics); if (ReturnType.ContainsNullableReferenceTypes()) { this.DeclaringCompilation.EnsureNullableAttributeExists(diagnostics, location, modifyCompilation: true); - ReportNullableReferenceTypesIfNeeded(diagnostics, location); } - ParameterHelpers.ReportAnnotatedUnconstrainedTypeParameters(Parameters, diagnostics); ParameterHelpers.EnsureNullableAttributeExists(Parameters, diagnostics, modifyCompilation: true); - ParameterHelpers.ReportNullableReferenceTypesIfNeeded(Parameters, diagnostics); } /// diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbol.cs index 9532856282b6a..7c4e9299f1401 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbol.cs @@ -769,16 +769,12 @@ internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, ParameterHelpers.EnsureIsReadOnlyAttributeExists(Parameters, diagnostics, modifyCompilation: true); - this.Type.ReportAnnotatedUnconstrainedTypeParameterIfAny(location, diagnostics); if (this.Type.ContainsNullableReferenceTypes()) { DeclaringCompilation.EnsureNullableAttributeExists(diagnostics, location, modifyCompilation: true); - ReportNullableReferenceTypesIfNeeded(diagnostics, location); } - ParameterHelpers.ReportAnnotatedUnconstrainedTypeParameters(this.Parameters, diagnostics); ParameterHelpers.EnsureNullableAttributeExists(this.Parameters, diagnostics, modifyCompilation: true); - ParameterHelpers.ReportNullableReferenceTypesIfNeeded(this.Parameters, diagnostics); } private void CheckAccessibility(Location location, DiagnosticBag diagnostics) diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceUserDefinedOperatorSymbolBase.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceUserDefinedOperatorSymbolBase.cs index 062fcbb525dcf..d02268c3ec2a4 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceUserDefinedOperatorSymbolBase.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceUserDefinedOperatorSymbolBase.cs @@ -650,15 +650,12 @@ internal sealed override void AfterAddingTypeMembersChecks(ConversionsBase conve ParameterHelpers.EnsureIsReadOnlyAttributeExists(Parameters, diagnostics, modifyCompilation: true); var location = ReturnTypeSyntax.Location; - ReturnType.ReportAnnotatedUnconstrainedTypeParameterIfAny(location, diagnostics); if (ReturnType.ContainsNullableReferenceTypes()) { this.DeclaringCompilation.EnsureNullableAttributeExists(diagnostics, location, modifyCompilation: true); - ReportNullableReferenceTypesIfNeeded(diagnostics, location); } - ParameterHelpers.ReportAnnotatedUnconstrainedTypeParameters(Parameters, diagnostics); + ParameterHelpers.EnsureNullableAttributeExists(Parameters, diagnostics, modifyCompilation: true); - ParameterHelpers.ReportNullableReferenceTypesIfNeeded(Parameters, diagnostics); } } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/TypeParameterConstraintClause.cs b/src/Compilers/CSharp/Portable/Symbols/Source/TypeParameterConstraintClause.cs index c82a6d90450f2..9cb7e97df5d9a 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/TypeParameterConstraintClause.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/TypeParameterConstraintClause.cs @@ -29,36 +29,31 @@ internal sealed class TypeParameterConstraintClause internal static readonly TypeParameterConstraintClause Empty = new TypeParameterConstraintClause( TypeParameterConstraintKind.None, ImmutableArray.Empty, - clauseSyntax: default, typeConstraintsSyntax: default, otherPartialDeclarations: ImmutableArray.Empty); internal static TypeParameterConstraintClause Create( TypeParameterConstraintKind constraints, ImmutableArray constraintTypes, - TypeParameterConstraintClauseSyntax clauseSyntax = default, ImmutableArray typeConstraintsSyntax = default) { Debug.Assert(!constraintTypes.IsDefault); if (constraints == TypeParameterConstraintKind.None && constraintTypes.IsEmpty) { - Debug.Assert(clauseSyntax is null); Debug.Assert(typeConstraintsSyntax.IsDefault); return Empty; } - return new TypeParameterConstraintClause(constraints, constraintTypes, clauseSyntax, typeConstraintsSyntax, otherPartialDeclarations: ImmutableArray.Empty); + return new TypeParameterConstraintClause(constraints, constraintTypes, typeConstraintsSyntax, otherPartialDeclarations: ImmutableArray.Empty); } private TypeParameterConstraintClause( TypeParameterConstraintKind constraints, ImmutableArray constraintTypes, - TypeParameterConstraintClauseSyntax clauseSyntax, ImmutableArray typeConstraintsSyntax, ImmutableArray otherPartialDeclarations) { this.Constraints = constraints; this.ConstraintTypes = constraintTypes; - this.ClauseSyntax = clauseSyntax; this.TypeConstraintsSyntax = typeConstraintsSyntax; this.OtherPartialDeclarations = otherPartialDeclarations; } @@ -66,11 +61,6 @@ private TypeParameterConstraintClause( public readonly TypeParameterConstraintKind Constraints; public readonly ImmutableArray ConstraintTypes; - /// - /// Syntax for the constraint clause. Populated from early constraint checking step only. - /// - internal readonly TypeParameterConstraintClauseSyntax ClauseSyntax; - /// /// Syntax for the constraint types. Populated from early constraint checking step only. /// @@ -84,11 +74,11 @@ private TypeParameterConstraintClause( internal bool IsEmpty => Constraints == TypeParameterConstraintKind.None && ConstraintTypes.IsEmpty; - internal bool IsEarly => !(ClauseSyntax is null); + internal bool IsEarly => !TypeConstraintsSyntax.IsDefault; internal TypeParameterConstraintClause AddPartialDeclaration(TypeParameterConstraintClause other) { - return new TypeParameterConstraintClause(Constraints, ConstraintTypes, ClauseSyntax, TypeConstraintsSyntax, OtherPartialDeclarations.Add(other)); + return new TypeParameterConstraintClause(Constraints, ConstraintTypes, TypeConstraintsSyntax, OtherPartialDeclarations.Add(other)); } } diff --git a/src/Compilers/CSharp/Portable/Symbols/SubstitutedTypeParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/SubstitutedTypeParameterSymbol.cs index 4ce3622647df3..8e4d3e7d6548d 100644 --- a/src/Compilers/CSharp/Portable/Symbols/SubstitutedTypeParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/SubstitutedTypeParameterSymbol.cs @@ -100,7 +100,7 @@ internal override ImmutableArray GetConstraintTypes(C { var constraintTypes = ArrayBuilder.GetInstance(); _map.SubstituteTypesDistinctWithoutModifiers(_underlyingTypeParameter.GetConstraintTypes(inProgress, early), constraintTypes, null); - return constraintTypes.ToImmutableAndFree().WhereAsArray(s_isNotObjectFunc); + return constraintTypes.ToImmutableAndFree().WhereAsArray(type => type.SpecialType != SpecialType.System_Object || !type.IsAnnotated); } internal override ImmutableArray GetInterfaces(ConsList inProgress) @@ -117,7 +117,5 @@ internal override TypeSymbol GetDeducedBaseType(ConsList in { return _map.SubstituteType(_underlyingTypeParameter.GetDeducedBaseType(inProgress)).AsTypeSymbolOnly(); } - - private static readonly Func s_isNotObjectFunc = type => type.SpecialType != SpecialType.System_Object; } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Symbol.cs b/src/Compilers/CSharp/Portable/Symbols/Symbol.cs index b59cd45d19ab9..2fd2334327b19 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Symbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Symbol.cs @@ -854,43 +854,6 @@ public virtual bool? NonNullTypes } } - internal void ReportNullableReferenceTypesIfNeeded(DiagnosticBag diagnostics, Location location) - { - ReportNullableReferenceTypesIfNeeded(this.DeclaringCompilation, nonNullTypesContext: this, diagnostics, location); - } - - /// - /// A `?` annotation on a type that isn't a value type causes: - /// - an error before C# 8.0 - /// - a warning outside of a NonNullTypes context - /// - internal static void ReportNullableReferenceTypesIfNeeded(CSharpCompilation compilation, INonNullTypesContext nonNullTypesContext, DiagnosticBag diagnostics, Location location) - { - var diagnostic = ReportNullableReferenceTypesIfNeeded(compilation, nonNullTypesContext); - if (diagnostic != null) - { - diagnostics.Add(diagnostic, location); - } - } - - internal static DiagnosticInfo ReportNullableReferenceTypesIfNeeded(CSharpCompilation compilation, INonNullTypesContext nonNullTypesContext) - { - var featureID = MessageID.IDS_FeatureStaticNullChecking; - if (!compilation.IsFeatureEnabled(featureID)) - { - LanguageVersion availableVersion = compilation.LanguageVersion; - LanguageVersion requiredVersion = featureID.RequiredVersion(); - - return new CSDiagnosticInfo(availableVersion.GetErrorCode(), featureID.Localize(), new CSharpRequiredLanguageVersion(requiredVersion)); - } - else if (nonNullTypesContext.NonNullTypes != true) - { - return new CSDiagnosticInfo(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation); - } - - return null; - } - internal DiagnosticInfo GetUseSiteDiagnosticForSymbolOrContainingType() { var info = this.GetUseSiteDiagnostic(); diff --git a/src/Compilers/CSharp/Portable/Symbols/TypeParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/TypeParameterSymbol.cs index 0eae9bdd2cf46..1ada48dc3f5b7 100644 --- a/src/Compilers/CSharp/Portable/Symbols/TypeParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/TypeParameterSymbol.cs @@ -444,15 +444,14 @@ internal bool IsReferenceTypeFromConstraintTypes(ImmutableArray ConstraintImpliesReferenceType(type.TypeSymbol, arg)); } - internal bool? IsNotNullableIfReferenceTypeFromConstraintTypes(ImmutableArray constraintTypes, ConsList inProgress) + internal static bool? IsNotNullableIfReferenceTypeFromConstraintTypes(ImmutableArray constraintTypes) { Debug.Assert(!constraintTypes.IsDefaultOrEmpty); - inProgress = inProgress.Prepend(this); bool? result = false; foreach (TypeSymbolWithAnnotations constraintType in constraintTypes) { - bool? fromType = IsNotNullableIfReferenceTypeFromConstraintType(constraintType, inProgress); + bool? fromType = IsNotNullableIfReferenceTypeFromConstraintType(constraintType); if (fromType == true) { return true; @@ -466,7 +465,7 @@ internal bool IsReferenceTypeFromConstraintTypes(ImmutableArray inProgress) + internal static bool? IsNotNullableIfReferenceTypeFromConstraintType(TypeSymbolWithAnnotations constraintType) { if (constraintType.IsAnnotated) { @@ -475,7 +474,7 @@ internal bool IsReferenceTypeFromConstraintTypes(ImmutableArray inProgress) public sealed override bool IsReferenceType => GetIsReferenceType(ConsList.Empty); - internal bool? GetIsNotNullableIfReferenceType(ConsList inProgress) + internal bool? GetIsNotNullableIfReferenceType() { - if (inProgress.ContainsReference(this)) - { - return false; - } - bool? fromReferenceTypeConstraint = false; if (this.HasReferenceTypeConstraint) @@ -554,14 +548,14 @@ internal bool GetIsReferenceType(ConsList inProgress) } } - ImmutableArray constraintTypes = this.GetConstraintTypesNoUseSiteDiagnostics(inProgress, early: true); + ImmutableArray constraintTypes = this.ConstraintTypesNoUseSiteDiagnostics; if (constraintTypes.IsEmpty) { return fromReferenceTypeConstraint; } - bool? fromTypes = IsNotNullableIfReferenceTypeFromConstraintTypes(constraintTypes, inProgress); + bool? fromTypes = IsNotNullableIfReferenceTypeFromConstraintTypes(constraintTypes); if (fromTypes == true || fromReferenceTypeConstraint == false) { @@ -574,7 +568,7 @@ internal bool GetIsReferenceType(ConsList inProgress) } // https://github.com/dotnet/roslyn/issues/26198 Should this API be exposed through ITypeParameterSymbol? - internal bool? IsNotNullableIfReferenceType => GetIsNotNullableIfReferenceType(ConsList.Empty); + internal bool? IsNotNullableIfReferenceType => GetIsNotNullableIfReferenceType(); internal bool GetIsValueType(ConsList inProgress) { diff --git a/src/Compilers/CSharp/Portable/Symbols/TypeSymbolWithAnnotations.cs b/src/Compilers/CSharp/Portable/Symbols/TypeSymbolWithAnnotations.cs index d61054d91bec1..8327e336e03bb 100644 --- a/src/Compilers/CSharp/Portable/Symbols/TypeSymbolWithAnnotations.cs +++ b/src/Compilers/CSharp/Portable/Symbols/TypeSymbolWithAnnotations.cs @@ -571,19 +571,6 @@ public static bool ContainsAnnotatedUnconstrainedTypeParameter( return (object)typeParameter != null; } - public void ReportAnnotatedUnconstrainedTypeParameterIfAny(Location location, DiagnosticBag diagnostics) - { - if (ContainsAnnotatedUnconstrainedTypeParameter()) - { - ReportAnnotatedUnconstrainedTypeParameter(location, diagnostics); - } - } - - public static void ReportAnnotatedUnconstrainedTypeParameter(Location location, DiagnosticBag diagnostics) - { - diagnostics.Add(ErrorCode.ERR_NullableUnconstrainedTypeParameter, location ?? NoLocation.Singleton); - } - public void AddNullableTransforms(ArrayBuilder transforms) { var typeSymbol = TypeSymbol; diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf index a9442fa4a73c5..95e9385bfe76f 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf @@ -22,6 +22,11 @@ An out variable cannot be declared as a ref local + + object generic type constraint + object generic type constraint + + injected declaration injected declaration diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf index 2c2ce74d94b04..15001f26c6bbf 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf @@ -22,6 +22,11 @@ An out variable cannot be declared as a ref local + + object generic type constraint + object generic type constraint + + injected declaration injected declaration diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf index d70920675947d..42d4721958d59 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf @@ -22,6 +22,11 @@ An out variable cannot be declared as a ref local + + object generic type constraint + object generic type constraint + + injected declaration injected declaration diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf index 70ecea599aedf..dabbf46ce82c8 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf @@ -22,6 +22,11 @@ An out variable cannot be declared as a ref local + + object generic type constraint + object generic type constraint + + injected declaration injected declaration diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf index 39665a47be9f9..33d5aa8d0da53 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf @@ -22,6 +22,11 @@ An out variable cannot be declared as a ref local + + object generic type constraint + object generic type constraint + + injected declaration injected declaration diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf index a0fcb5b5faa05..6cbd919499c2b 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf @@ -22,6 +22,11 @@ An out variable cannot be declared as a ref local + + object generic type constraint + object generic type constraint + + injected declaration injected declaration diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf index 1a6dc61497dd3..604d94353f64a 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf @@ -22,6 +22,11 @@ An out variable cannot be declared as a ref local + + object generic type constraint + object generic type constraint + + injected declaration injected declaration diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf index be070477883e2..be77209634c6e 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf @@ -22,6 +22,11 @@ An out variable cannot be declared as a ref local + + object generic type constraint + object generic type constraint + + injected declaration injected declaration diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf index bbb6c85ecc7e2..95b20564999c7 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf @@ -22,6 +22,11 @@ An out variable cannot be declared as a ref local + + object generic type constraint + object generic type constraint + + injected declaration injected declaration diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf index 7843f43ff360d..fd1189dbcbd34 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf @@ -22,6 +22,11 @@ An out variable cannot be declared as a ref local + + object generic type constraint + object generic type constraint + + injected declaration injected declaration diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf index 89b725abef955..04f82c58d043e 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf @@ -22,6 +22,11 @@ An out variable cannot be declared as a ref local + + object generic type constraint + object generic type constraint + + injected declaration injected declaration diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf index 5e7510b91c707..8f884996fa323 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf @@ -22,6 +22,11 @@ An out variable cannot be declared as a ref local + + object generic type constraint + object generic type constraint + + injected declaration injected declaration diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf index 917ce01e0a7bf..3178266839734 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf @@ -22,6 +22,11 @@ An out variable cannot be declared as a ref local + + object generic type constraint + object generic type constraint + + injected declaration injected declaration diff --git a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_Nullable.cs b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_Nullable.cs index b75503faef03f..fa5d8f9ae6d10 100644 --- a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_Nullable.cs +++ b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_Nullable.cs @@ -171,9 +171,9 @@ public class Attribute references: new[] { ref0 }, parseOptions: TestOptions.Regular8); comp.VerifyEmitDiagnostics( - // (3,5): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (3,11): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // object? F() => null; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "object?").WithLocation(3, 5), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(3, 11), // error CS0518: Predefined type 'System.Boolean' is not defined or imported Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Boolean").WithLocation(1, 1)); } @@ -202,9 +202,9 @@ public struct Boolean { } references: new[] { ref0 }, parseOptions: TestOptions.Regular8); comp.VerifyEmitDiagnostics( - // (3,5): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (3,11): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // object? F() => null; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "object?").WithLocation(3, 5), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(3, 11), // error CS0518: Predefined type 'System.Attribute' is not defined or imported Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Attribute").WithLocation(1, 1)); } @@ -238,9 +238,9 @@ public Attribute(object o) { } references: new[] { ref0 }, parseOptions: TestOptions.Regular8); comp.VerifyEmitDiagnostics( - // (3,5): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (3,11): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // object? F() => null; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "object?").WithLocation(3, 5), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(3, 11), // error CS1729: 'Attribute' does not contain a constructor that takes 0 arguments Diagnostic(ErrorCode.ERR_BadCtorArgCount).WithArguments("System.Attribute", "0").WithLocation(1, 1), // error CS1729: 'Attribute' does not contain a constructor that takes 0 arguments diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/ForEachTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/ForEachTests.cs index b18b2a2d0f53f..dd2d5c7e301a4 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/ForEachTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/ForEachTests.cs @@ -2241,9 +2241,10 @@ void Goo(System.Collections.Generic.IEnumerable? e) "; var comp = CreateEmptyCompilation(text); comp.VerifyDiagnostics( - // (28,14): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (28,55): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // void Goo(System.Collections.Generic.IEnumerable? e) - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "System.Collections.Generic.IEnumerable? e").WithLocation(28, 14)); + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(28, 55) + ); } [WorkItem(798000, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/798000")] @@ -2285,9 +2286,9 @@ void Goo(System.Collections.Generic.IEnumerable? e) "; var comp = CreateEmptyCompilation(text, parseOptions: TestOptions.Regular7_3, skipUsesIsNullable: true); comp.VerifyDiagnostics( - // (28,14): error CS8370: Feature 'static null checking' is not available in C# 7.3. Please use language version 8.0 or greater. + // (28,55): error CS8370: Feature 'static null checking' is not available in C# 7.3. Please use language version 8.0 or greater. // void Goo(System.Collections.Generic.IEnumerable? e) - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "System.Collections.Generic.IEnumerable? e").WithArguments("static null checking", "8.0").WithLocation(28, 14) + Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "?").WithArguments("static null checking", "8.0").WithLocation(28, 55) ); } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/LocalFunctionTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/LocalFunctionTests.cs index f31cd2a403a8d..d31dda7f31e1a 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/LocalFunctionTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/LocalFunctionTests.cs @@ -558,12 +558,13 @@ public void BadGenericConstraint() var comp = CreateCompilation(@" class C { - public void M(T value) where T : object { } + public void M(T value) where T : class, object { } }"); comp.VerifyDiagnostics( - // (4,41): error CS0702: Constraint cannot be special class 'object' - // public void M(T value) where T : object { } - Diagnostic(ErrorCode.ERR_SpecialTypeAsBound, "object").WithArguments("object").WithLocation(4, 41)); + // (4,48): error CS0450: 'object': cannot specify both a constraint class and the 'class' or 'struct' constraint + // public void M(T value) where T : class, object { } + Diagnostic(ErrorCode.ERR_RefValBoundWithClass, "object").WithArguments("object").WithLocation(4, 48) + ); } [Fact] diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs index 613810f544044..e463ef08661de 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs @@ -109,9 +109,9 @@ public class C // (5,12): error CS0246: The type or namespace name 'Unknown' could not be found (are you missing a using directive or an assembly reference?) // public Unknown? field2; Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "Unknown").WithArguments("Unknown").WithLocation(5, 12), - // (4,15): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // (4,12): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public T? field; - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "field").WithLocation(4, 15), + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(4, 12), // (2,14): warning CS8618: Non-nullable field 'field' is uninitialized. // public class C Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("field", "field").WithLocation(2, 14) @@ -454,66 +454,66 @@ class D3 } "; var expectedDiagnostics = new[] { - // (5,12): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (5,18): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // static string? P // warn 3 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "string?").WithLocation(5, 12), - // (13,12): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(5, 18), + // (13,18): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // static string? MethodWithLocalFunction() // warn 5 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "string?").WithLocation(13, 12), - // (24,12): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(13, 18), + // (24,18): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // static string? Lambda() // warn 11 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "string?").WithLocation(24, 12), - // (33,22): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(24, 18), + // (33,32): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // static string M2(out string? x4) => throw null; // warn 16 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "out string? x4").WithLocation(33, 22), - // (34,22): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(33, 32), + // (34,30): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // static string M3(C x, C y) => throw null; // warn 17 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "C x").WithLocation(34, 22), - // (36,23): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(34, 30), + // (36,21): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // event MyDelegate? Event; // warn 20 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "Event").WithLocation(36, 23), - // (40,19): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(36, 21), + // (40,47): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public static C operator +(C x, C y) => throw null; // warn 24 and 25 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "C").WithLocation(40, 19), - // (40,19): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(40, 47), + // (40,46): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public static C operator +(C x, C y) => throw null; // warn 24 and 25 - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "C").WithLocation(40, 19), - // (40,44): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(40, 46), + // (40,22): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public static C operator +(C x, C y) => throw null; // warn 24 and 25 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "C y").WithLocation(40, 44), - // (40,44): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(40, 22), + // (40,21): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public static C operator +(C x, C y) => throw null; // warn 24 and 25 - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "C y").WithLocation(40, 44), - // (45,12): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(40, 21), + // (45,33): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public string? this[C x] { get => throw null; } // warn 27 and 28 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "string?").WithLocation(45, 12), - // (45,25): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(45, 33), + // (45,18): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public string? this[C x] { get => throw null; } // warn 27 and 28 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "C x").WithLocation(45, 25), - // (4,20): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(45, 18), + // (4,18): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // static string? field = M2(out string? x1); // warn 1 and 2 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "field").WithLocation(4, 20), - // (43,12): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(4, 18), + // (43,15): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // D3(C x) => throw null; // warn 26 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "C x").WithLocation(43, 12), - // (43,12): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(43, 15), + // (43,14): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // D3(C x) => throw null; // warn 26 - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "C x").WithLocation(43, 12), - // (35,14): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(43, 14), + // (35,20): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // delegate string? MyDelegate(C x); // warn 18 and 19 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "string?").WithLocation(35, 14), - // (35,33): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(35, 20), + // (35,41): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // delegate string? MyDelegate(C x); // warn 18 and 19 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "C x").WithLocation(35, 33), - // (38,28): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(35, 41), + // (38,29): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // class D where T2 : T? { } // warn 22 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "T?").WithLocation(38, 28), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(38, 29), // (38,28): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // class D where T2 : T? { } // warn 22 Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(38, 28), - // (39,11): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (39,24): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // class D2 : C { } // warn 23 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "D2").WithLocation(39, 11), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(39, 24), // (4,41): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // static string? field = M2(out string? x1); // warn 1 and 2 Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(4, 41), @@ -553,7 +553,6 @@ class D3 }; // PROTOTYPE(NullableReferenceTypes): are annotations on events meaningful/allowed? - // PROTOTYPE(NullableReferenceTypes): locations aren't great var c = CreateCompilation(source); c.VerifyDiagnostics(expectedDiagnostics); @@ -608,25 +607,25 @@ public class E where T : struct } "; CSharpCompilation c = CreateCompilation(source); - // PROTOTYPE(NullableReferenceTypes): ERR_NullableUnconstrainedTypeParameter is missing for - // (6,10): - // T? y1 = x1; // warn 3 c.VerifyDiagnostics( - // (4,12): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (4,18): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public T? M(T? x1) // warn 1 and 2 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "T?").WithLocation(4, 12), - // (4,12): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(4, 18), + // (4,17): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public T? M(T? x1) // warn 1 and 2 - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(4, 12), - // (4,17): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(4, 17), + // (4,13): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public T? M(T? x1) // warn 1 and 2 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "T? x1").WithLocation(4, 17), - // (4,17): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(4, 13), + // (4,12): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public T? M(T? x1) // warn 1 and 2 - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T? x1").WithLocation(4, 17), + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(4, 12), // (6,10): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // T? y1 = x1; // warn 3 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(6, 10) + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(6, 10), + // (6,9): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // T? y1 = x1; // warn 3 + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(6, 9) ); var client = @" @@ -1593,9 +1592,9 @@ public enum AttributeTargets { Assembly = 1, Module = 2, Class = 4, Struct = 8, "; var comp = CreateEmptyCompilation(lib); comp.VerifyDiagnostics( - // (11,16): warning CS8632: The annotation for nullable reference types can only be used in code within a '[NonNullTypes(true)]' context. + // (11,22): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public String? Concat(String a, String b) => throw null; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "String?").WithLocation(11, 16) + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(11, 22) ); var comp2 = CreateEmptyCompilation("", references: new[] { comp.EmitToImageReference() }); @@ -2425,9 +2424,9 @@ public class External var libComp = CreateCompilation(new[] { lib, NonNullTypesTrue, NonNullTypesAttributesDefinition }); libComp.VerifyDiagnostics( - // (13,27): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (13,25): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public static string? fns; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "fns").WithLocation(13, 27) + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(13, 25) ); verifyExternal(libComp); @@ -2516,9 +2515,9 @@ public void M() compilation.VerifyTypes(); compilation.VerifyDiagnostics( - // (49,27): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (49,25): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public static string? ns; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "ns").WithLocation(49, 27), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(49, 25), // (58,36): warning CS8625: Cannot convert null literal to non-nullable reference or unconstrained type parameter. // External.s /*T:string!*/ = null; // warn 1 Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(58, 36), @@ -2708,9 +2707,9 @@ public void M() compilation.VerifyTypes(); compilation.VerifyDiagnostics( - // (39,34): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (39,31): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public static List3 ns; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "ns").WithLocation(39, 34), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(39, 31), // (48,41): warning CS8625: Cannot convert null literal to non-nullable reference or unconstrained type parameter. // External.s.Item /*T:string!*/ = null; // warn 1 Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(48, 41), @@ -2810,9 +2809,9 @@ public void M() compilation.VerifyTypes(); compilation.VerifyDiagnostics( - // (33,42): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (33,36): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public static (string s, string? ns) t; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "t").WithLocation(33, 42), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(33, 36), // (42,38): warning CS8625: Cannot convert null literal to non-nullable reference or unconstrained type parameter. // External.t.s /*T:string!*/ = null; // warn 1 Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(42, 38), @@ -2918,9 +2917,9 @@ public void M() compilation.VerifyTypes(); compilation.VerifyDiagnostics( - // (38,29): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (38,25): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public static string?[] ns; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "ns").WithLocation(38, 29), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(38, 25), // (47,39): warning CS8625: Cannot convert null literal to non-nullable reference or unconstrained type parameter. // External.s[0] /*T:string!*/ = null; // warn 1 Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(47, 39), @@ -3029,9 +3028,9 @@ public void M() compilation.VerifyTypes(); compilation.VerifyDiagnostics( - // (39,19): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (39,25): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public static string? ns { get; set; } - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "string?").WithLocation(39, 19), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(39, 25), // (48,36): warning CS8625: Cannot convert null literal to non-nullable reference or unconstrained type parameter. // External.s /*T:string!*/ = null; // warn 1 Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(48, 36), @@ -3219,12 +3218,12 @@ public void M() compilation.VerifyTypes(); compilation.VerifyDiagnostics( - // (38,19): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (38,41): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public static string? NMethod(string? ns) => throw null; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "string?").WithLocation(38, 19), - // (38,35): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(38, 41), + // (38,25): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public static string? NMethod(string? ns) => throw null; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "string? ns").WithLocation(38, 35), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(38, 25), // (47,25): warning CS8625: Cannot convert null literal to non-nullable reference or unconstrained type parameter. // External.Method(null) /*T:string!*/; // warn 1 Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(47, 25), @@ -3560,9 +3559,9 @@ public void M2() compilation.VerifyTypes(); compilation.VerifyDiagnostics( - // (60,5): warning CS8632: The annotation for nullable reference types can only be used in code within a '[NonNullTypes(true)]' context. + // (60,11): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // string?[] FalseNCollection() => throw null; // 5 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "string?[]").WithLocation(60, 5), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(60, 11), // (16,13): warning CS8602: Possible dereference of a null reference. // ns /*T:string?*/ .ToString(); // 1 Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "ns").WithLocation(16, 13), @@ -3647,9 +3646,9 @@ public void M2() compilation.VerifyTypes(); compilation.VerifyDiagnostics( - // (60,5): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (60,11): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // string?[] FalseNCollection() => throw null; // 7 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "string?[]").WithLocation(60, 5), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(60, 11), // (14,24): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // foreach (string? ns in NCollection()) // 1 Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(14, 24), @@ -3732,9 +3731,9 @@ public void M() compilation.VerifyTypes(); compilation.VerifyDiagnostics( - // (52,20): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (52,30): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // void FalseNOut(out string? ns) => throw null; // warn 7 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "out string? ns").WithLocation(52, 20), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(52, 30), // (11,14): warning CS8600: Converting null literal or possible null value to non-nullable type. // s2 = null; // warn 1 Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "null").WithLocation(11, 14), @@ -3820,9 +3819,9 @@ public void M() compilation.VerifyTypes(); compilation.VerifyDiagnostics( - // (52,20): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (52,30): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // void FalseNOut(out string? ns) => throw null; // 8 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "out string? ns").WithLocation(52, 20), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(52, 30), // (13,24): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // NOut(out string? ns2); // 1 Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(13, 24), @@ -3910,9 +3909,9 @@ public class Base compilation.VerifyTypes(); compilation.VerifyDiagnostics( - // (54,12): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (54,18): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public string? FalseNMethod() => throw null; // warn 8 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "string?").WithLocation(54, 12), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(54, 18), // (11,14): warning CS8600: Converting null literal or possible null value to non-nullable type. // s2 = null; // warn 1 Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "null").WithLocation(11, 14), @@ -4000,9 +3999,9 @@ public class Base compilation.VerifyTypes(); compilation.VerifyDiagnostics( - // (54,12): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (54,18): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public string? FalseNMethod() => throw null; // 8 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "string?").WithLocation(54, 12), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(54, 18), // (13,15): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // string? ns2 = NMethod(); // 1 Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(13, 15), @@ -4208,9 +4207,9 @@ public void M(T t, NT nt) compilation.VerifyTypes(); compilation.VerifyDiagnostics( - // (23,16): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (23,22): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // where NT : List // warn 3 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "List").WithLocation(23, 16), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(23, 22), // (29,9): warning CS8602: Possible dereference of a null reference. // nt.Item /*T:S?*/ .ToString(); // warn 4 Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "nt.Item").WithLocation(29, 9), @@ -4257,12 +4256,13 @@ class C3 }"; var comp = CreateCompilation(new[] { source, NonNullTypesAttributesDefinition }); comp.VerifyDiagnostics( - // (6,5): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (6,11): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // string? F2() => throw null; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "string?").WithLocation(6, 5), - // (15,5): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(6, 11), + // (15,11): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // string? F2() => throw null; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "string?").WithLocation(15, 5)); + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(15, 11) + ); verify("C1.F1", "System.String", isAnnotated: false, isNullable: null); verify("C1.F2", "System.String?", isAnnotated: true, isNullable: true); @@ -4335,12 +4335,12 @@ class C3 // (6,5): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // T? F2() => throw null; Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(6, 5), - // (6,5): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (6,6): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // T? F2() => throw null; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "T?").WithLocation(6, 5), - // (8,5): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(6, 6), + // (8,6): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // T? F4() where T : class => throw null; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "T?").WithLocation(8, 5), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(8, 6), // (8,5): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // T? F4() where T : class => throw null; Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(8, 5), @@ -4350,12 +4350,12 @@ class C3 // (28,5): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // T? F2() => throw null; Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(28, 5), - // (17,5): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (17,6): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // T? F2() => throw null; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "T?").WithLocation(17, 5), - // (19,5): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(17, 6), + // (19,6): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // T? F4() where T : class => throw null; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "T?").WithLocation(19, 5), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(19, 6), // (19,5): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // T? F4() where T : class => throw null; Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(19, 5) @@ -4816,7 +4816,7 @@ public override void M1(T? x) where T : struct Diagnostic(ErrorCode.ERR_CantOverrideNonVirtual, "M1").WithArguments("B.M1(T?)", "A.M1(T)").WithLocation(11, 26), // (11,32): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public override void M1(T? x) where T : struct - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T? x").WithLocation(11, 32) + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(11, 32) ); var b = compilation.GetTypeByMetadataName("B"); @@ -4873,7 +4873,7 @@ public override void M4(T? x) compilation.VerifyDiagnostics( // (8,23): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public void M2(T? x) - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T? x").WithLocation(8, 23), + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(8, 23), // (27,26): error CS0506: 'B.M2(T?)': cannot override inherited member 'A.M2(T?)' because it is not marked virtual, abstract, or override // public override void M2(T? x) Diagnostic(ErrorCode.ERR_CantOverrideNonVirtual, "M2").WithArguments("B.M2(T?)", "A.M2(T?)").WithLocation(27, 26), @@ -4888,16 +4888,16 @@ public override void M4(T? x) Diagnostic(ErrorCode.ERR_CantOverrideNonVirtual, "M1").WithArguments("B.M1(T?)", "A.M1(T)").WithLocation(23, 26), // (23,32): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public override void M1(T? x) - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T? x").WithLocation(23, 32), + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(23, 32), // (27,32): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public override void M2(T? x) - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T? x").WithLocation(27, 32), + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(27, 32), // (31,32): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public override void M3(T? x) - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T? x").WithLocation(31, 32), + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(31, 32), // (35,32): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public override void M4(T? x) - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T? x").WithLocation(35, 32) + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(35, 32) ); var b = compilation.GetTypeByMetadataName("B"); @@ -4944,7 +4944,7 @@ public override void M1(T? x) Diagnostic(ErrorCode.ERR_OverrideNotExpected, "M1").WithArguments("B.M1(T?)").WithLocation(11, 26), // (11,32): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public override void M1(T? x) - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T? x").WithLocation(11, 32) + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(11, 32) ); var b = compilation.GetTypeByMetadataName("B"); @@ -5535,15 +5535,16 @@ public class Class : Base "; var comp = CreateCompilation(new[] { source, NonNullTypesAttributesDefinition }); comp.VerifyDiagnostics( - // (7,20): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // (7,25): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public virtual List P { get; set; } = default; - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "List").WithLocation(7, 20), - // (12,21): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(7, 25), + // (12,26): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public override List P { get; set; } = default; - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "List").WithLocation(12, 21), - // (12,21): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(12, 26), + // (12,27): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public override List P { get; set; } = default; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "List").WithLocation(12, 21)); + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(12, 27) + ); } [Fact] @@ -5565,9 +5566,9 @@ public class Class : Base where T : class "; var comp = CreateCompilation(new[] { source, NonNullTypesAttributesDefinition }); comp.VerifyDiagnostics( - // (12,21): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (12,27): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public override List P { get; set; } = default; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "List").WithLocation(12, 21) + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(12, 27) ); } @@ -5691,12 +5692,12 @@ void Dummy() // (27,50): warning CS8608: Nullability of reference types in type doesn't match overridden member. // public override event System.Action E1; // 3, 4 Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeOnOverride, "E1").WithLocation(27, 50), - // (27,50): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (27,47): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public override event System.Action E1; // 3, 4 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "E1").WithLocation(27, 50), - // (19,50): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(27, 47), + // (19,47): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public override event System.Action E1 {add {} remove{}} // 1, 2 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "E1").WithLocation(19, 50) + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(19, 47) ); } @@ -6033,18 +6034,18 @@ public override string[]? this[short x] // 4 var compilation = CreateCompilation(new[] { source, NonNullTypesAttributesDefinition }); compilation.VerifyDiagnostics( - // (14,21): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (14,27): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public abstract string?[] this[int x] {get; set;} // 2 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "string?[]").WithLocation(14, 21), - // (11,21): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(14, 27), + // (11,27): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public abstract string?[] P1 {get; set;} // 1 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "string?[]").WithLocation(11, 21), - // (23,21): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(11, 27), + // (23,29): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public override string[]? P2 {get; set;} // 3 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "string[]?").WithLocation(23, 21), - // (33,21): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(23, 29), + // (33,29): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public override string[]? this[short x] // 4 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "string[]?").WithLocation(33, 21) + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(33, 29) ); } @@ -6329,12 +6330,12 @@ class B : A // (18,31): warning CS8609: Nullability of reference types in return type doesn't match overridden member. // public override string?[] M1() Diagnostic(ErrorCode.WRN_NullabilityMismatchInReturnTypeOnOverride, "M1").WithLocation(18, 31), - // (24,21): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (24,22): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public override S?[] M2() - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "S?[]").WithLocation(24, 21), - // (18,21): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(24, 22), + // (18,27): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public override string?[] M1() - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "string?[]").WithLocation(18, 21), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(18, 27), // (20,26): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // return new string?[] {}; Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(20, 26), @@ -6511,12 +6512,12 @@ class B : IA // (11,18): warning CS8616: Nullability of reference types in return type doesn't match implemented member 'string[] IA.M1()'. // string?[] IA.M1() Diagnostic(ErrorCode.WRN_NullabilityMismatchInReturnTypeOnExplicitImplementation, "M1").WithArguments("string[] IA.M1()").WithLocation(11, 18), - // (17,5): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (17,6): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // S?[] IA.M2() - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "S?[]").WithLocation(17, 5), - // (11,5): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(17, 6), + // (11,11): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // string?[] IA.M1() - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "string?[]").WithLocation(11, 5), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(11, 11), // (13,26): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // return new string?[] {}; Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(13, 26), @@ -6552,15 +6553,15 @@ class B : IA // (12,17): warning CS8616: Nullability of reference types in return type doesn't match implemented member 'string?[] IA.M1()'. // string[] IA.M1() => throw null; Diagnostic(ErrorCode.WRN_NullabilityMismatchInReturnTypeOnExplicitImplementation, "M1").WithArguments("string?[] IA.M1()").WithLocation(12, 17), - // (7,5): warning CS8632: The annotation for nullable reference types can only be used in code within a '[NonNullTypes(true)]' context. + // (7,6): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // T?[] M2() where T : class; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "T?[]").WithLocation(7, 5), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(7, 6), // (7,5): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // T?[] M2() where T : class; - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?[]").WithLocation(7, 5), - // (5,5): warning CS8632: The annotation for nullable reference types can only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(7, 5), + // (5,11): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // string?[] M1(); - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "string?[]").WithLocation(5, 5) + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(5, 11) ); } @@ -6674,12 +6675,12 @@ public override void M2(T?[] x) // (13,26): warning CS8610: Nullability of reference types in type of parameter 'x' doesn't match overridden member. // public override void M1(string?[] x) Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOnOverride, "M1").WithArguments("x").WithLocation(13, 26), - // (18,32): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (18,33): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public override void M2(T?[] x) - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "T?[] x").WithLocation(18, 32), - // (13,29): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(18, 33), + // (13,35): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public override void M1(string?[] x) - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "string?[] x").WithLocation(13, 29) + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(13, 35) ); // PROTOTYPE(NullableReferenceTypes): should warn on B.M1 and B.M2 } @@ -7254,6 +7255,36 @@ partial void M1(T? x, T[]? y, System.Action z, System.Action?[]? u var compilation = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); compilation.VerifyDiagnostics( + // (10,25): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // partial void M1(T? x, T[]? y, System.Action z, System.Action?[]? u) where T : class + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(10, 25), + // (10,24): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // partial void M1(T? x, T[]? y, System.Action z, System.Action?[]? u) where T : class + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(10, 24), + // (10,33): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // partial void M1(T? x, T[]? y, System.Action z, System.Action?[]? u) where T : class + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(10, 33), + // (10,53): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // partial void M1(T? x, T[]? y, System.Action z, System.Action?[]? u) where T : class + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(10, 53), + // (10,52): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // partial void M1(T? x, T[]? y, System.Action z, System.Action?[]? u) where T : class + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(10, 52), + // (10,74): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // partial void M1(T? x, T[]? y, System.Action z, System.Action?[]? u) where T : class + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(10, 74), + // (10,73): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // partial void M1(T? x, T[]? y, System.Action z, System.Action?[]? u) where T : class + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(10, 73), + // (10,77): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // partial void M1(T? x, T[]? y, System.Action z, System.Action?[]? u) where T : class + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(10, 77), + // (10,79): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // partial void M1(T? x, T[]? y, System.Action z, System.Action?[]? u) where T : class + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(10, 79), + // (10,82): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // partial void M1(T? x, T[]? y, System.Action z, System.Action?[]? u) where T : class + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(10, 82), // (10,18): warning CS8611: Nullability of reference types in type of parameter 'x' doesn't match partial method declaration. // partial void M1(T? x, T[]? y, System.Action z, System.Action?[]? u) where T : class Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOnPartial, "M1").WithArguments("x").WithLocation(10, 18), @@ -7263,18 +7294,27 @@ partial void M1(T? x, T[]? y, System.Action z, System.Action?[]? u // (10,18): warning CS8611: Nullability of reference types in type of parameter 'z' doesn't match partial method declaration. // partial void M1(T? x, T[]? y, System.Action z, System.Action?[]? u) where T : class Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOnPartial, "M1").WithArguments("z").WithLocation(10, 18), - // (5,29): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (5,30): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // partial void M1(T x, T?[] y, System.Action z, System.Action?[]? u) where T : class; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "T?[] y").WithLocation(5, 29), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(5, 30), // (5,29): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // partial void M1(T x, T?[] y, System.Action z, System.Action?[]? u) where T : class; - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?[] y").WithLocation(5, 29), - // (5,57): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(5, 29), + // (5,72): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // partial void M1(T x, T?[] y, System.Action z, System.Action?[]? u) where T : class; + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(5, 72), + // (5,71): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // partial void M1(T x, T?[] y, System.Action z, System.Action?[]? u) where T : class; + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(5, 71), + // (5,75): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // partial void M1(T x, T?[] y, System.Action z, System.Action?[]? u) where T : class; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "System.Action?[]? u").WithLocation(5, 57), - // (5,57): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(5, 75), + // (5,77): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // partial void M1(T x, T?[] y, System.Action z, System.Action?[]? u) where T : class; - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "System.Action?[]? u").WithLocation(5, 57) + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(5, 77), + // (5,80): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // partial void M1(T x, T?[] y, System.Action z, System.Action?[]? u) where T : class; + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(5, 80) ); } @@ -7305,6 +7345,36 @@ partial void M1(T? x, T[]? y, System.Action z, System.Action?[]? u // (17,18): // partial void M1(T? x, T[]? y, System.Action z, System.Action?[]? u) where T : class compilation.VerifyDiagnostics( + // (17,25): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // partial void M1(T? x, T[]? y, System.Action z, System.Action?[]? u) where T : class + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(17, 25), + // (17,24): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // partial void M1(T? x, T[]? y, System.Action z, System.Action?[]? u) where T : class + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(17, 24), + // (17,33): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // partial void M1(T? x, T[]? y, System.Action z, System.Action?[]? u) where T : class + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(17, 33), + // (17,53): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // partial void M1(T? x, T[]? y, System.Action z, System.Action?[]? u) where T : class + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(17, 53), + // (17,52): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // partial void M1(T? x, T[]? y, System.Action z, System.Action?[]? u) where T : class + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(17, 52), + // (17,74): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // partial void M1(T? x, T[]? y, System.Action z, System.Action?[]? u) where T : class + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(17, 74), + // (17,73): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // partial void M1(T? x, T[]? y, System.Action z, System.Action?[]? u) where T : class + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(17, 73), + // (17,77): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // partial void M1(T? x, T[]? y, System.Action z, System.Action?[]? u) where T : class + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(17, 77), + // (17,79): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // partial void M1(T? x, T[]? y, System.Action z, System.Action?[]? u) where T : class + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(17, 79), + // (17,82): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // partial void M1(T? x, T[]? y, System.Action z, System.Action?[]? u) where T : class + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(17, 82), // (17,18): warning CS8611: Nullability of reference types in type of parameter 'x' doesn't match partial method declaration. // partial void M1(T? x, T[]? y, System.Action z, System.Action?[]? u) where T : class Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOnPartial, "M1").WithArguments("x").WithLocation(17, 18), @@ -7314,18 +7384,27 @@ partial void M1(T? x, T[]? y, System.Action z, System.Action?[]? u // (17,18): warning CS8611: Nullability of reference types in type of parameter 'z' doesn't match partial method declaration. // partial void M1(T? x, T[]? y, System.Action z, System.Action?[]? u) where T : class Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOnPartial, "M1").WithArguments("z").WithLocation(17, 18), - // (11,29): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (11,30): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // partial void M1(T x, T?[] y, System.Action z, System.Action?[]? u) where T : class; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "T?[] y").WithLocation(11, 29), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(11, 30), // (11,29): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // partial void M1(T x, T?[] y, System.Action z, System.Action?[]? u) where T : class; - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?[] y").WithLocation(11, 29), - // (11,57): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(11, 29), + // (11,72): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // partial void M1(T x, T?[] y, System.Action z, System.Action?[]? u) where T : class; + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(11, 72), + // (11,71): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // partial void M1(T x, T?[] y, System.Action z, System.Action?[]? u) where T : class; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "System.Action?[]? u").WithLocation(11, 57), - // (11,57): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(11, 71), + // (11,75): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // partial void M1(T x, T?[] y, System.Action z, System.Action?[]? u) where T : class; - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "System.Action?[]? u").WithLocation(11, 57) + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(11, 75), + // (11,77): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // partial void M1(T x, T?[] y, System.Action z, System.Action?[]? u) where T : class; + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(11, 77), + // (11,80): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // partial void M1(T x, T?[] y, System.Action z, System.Action?[]? u) where T : class; + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(11, 80) ); } @@ -17190,16 +17269,16 @@ object Test3() ", parseOptions: TestOptions.Regular7); c.VerifyDiagnostics( - // (10,18): error CS8107: Feature 'static null checking' is not available in C# 7. Please use language version 8.0 or greater. + // (10,18): error CS8107: Feature 'static null checking' is not available in C# 7.0. Please use language version 8.0 or greater. // object []? u1 = null; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7, "?").WithArguments("static null checking", "8.0").WithLocation(10, 18), - // (15,20): error CS8107: Feature 'static null checking' is not available in C# 7. Please use language version 8.0 or greater. + // (15,20): error CS8107: Feature 'static null checking' is not available in C# 7.0. Please use language version 8.0 or greater. // object [][]? u2 = null; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7, "?").WithArguments("static null checking", "8.0").WithLocation(15, 20), - // (20,18): error CS8107: Feature 'static null checking' is not available in C# 7. Please use language version 8.0 or greater. + // (20,18): error CS8107: Feature 'static null checking' is not available in C# 7.0. Please use language version 8.0 or greater. // object []?[]? u3 = null; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7, "?").WithArguments("static null checking", "8.0").WithLocation(20, 18), - // (20,21): error CS8107: Feature 'static null checking' is not available in C# 7. Please use language version 8.0 or greater. + // (20,21): error CS8107: Feature 'static null checking' is not available in C# 7.0. Please use language version 8.0 or greater. // object []?[]? u3 = null; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7, "?").WithArguments("static null checking", "8.0").WithLocation(20, 21) ); @@ -20906,12 +20985,21 @@ static void F5() where T5 : class // (13,14): error CS0304: Cannot create an instance of the variable type 'T2' because it does not have the new() constraint // x2 = new T2?(); // error 3 and 4 Diagnostic(ErrorCode.ERR_NoNewTyvar, "new T2?()").WithArguments("T2").WithLocation(13, 14), + // (13,18): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // x2 = new T2?(); // error 3 and 4 + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T2?").WithLocation(13, 18), // (14,14): error CS8630: Cannot use a nullable reference type in object creation. // x2 = new T2? { }; // error 5 and 6 Diagnostic(ErrorCode.ERR_AnnotationDisallowedInObjectCreation, "new T2? { }").WithArguments("T2").WithLocation(14, 14), // (14,14): error CS0304: Cannot create an instance of the variable type 'T2' because it does not have the new() constraint // x2 = new T2? { }; // error 5 and 6 Diagnostic(ErrorCode.ERR_NoNewTyvar, "new T2? { }").WithArguments("T2").WithLocation(14, 14), + // (14,18): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // x2 = new T2? { }; // error 5 and 6 + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T2?").WithLocation(14, 18), + // (15,19): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // x2 = (new T2?[1])[0]; + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T2?").WithLocation(15, 19), // (20,14): error CS8630: Cannot use a nullable reference type in object creation. // x3 = new T3?(); // error 7 Diagnostic(ErrorCode.ERR_AnnotationDisallowedInObjectCreation, "new T3?()").WithArguments("T3").WithLocation(20, 14), @@ -20921,12 +21009,21 @@ static void F5() where T5 : class // (27,14): error CS8630: Cannot use a nullable reference type in object creation. // x4 = new T4?(); // error 9 Diagnostic(ErrorCode.ERR_AnnotationDisallowedInObjectCreation, "new T4?()").WithArguments("T4").WithLocation(27, 14), + // (27,18): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // x4 = new T4?(); // error 9 + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T4?").WithLocation(27, 18), // (28,14): error CS8630: Cannot use a nullable reference type in object creation. // x4 = new T4? { }; // error 10 Diagnostic(ErrorCode.ERR_AnnotationDisallowedInObjectCreation, "new T4? { }").WithArguments("T4").WithLocation(28, 14), + // (28,18): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // x4 = new T4? { }; // error 10 + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T4?").WithLocation(28, 18), // (30,18): error CS0453: The type 'int?' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'Nullable' // x4 = new System.Nullable? { }; // error 11 Diagnostic(ErrorCode.ERR_ValConstraintNotSatisfied, "System.Nullable?").WithArguments("System.Nullable", "T", "int?").WithLocation(30, 18), + // (29,19): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // x4 = (new T4?[1])[0]; + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T4?").WithLocation(29, 19), // (35,14): error CS8630: Cannot use a nullable reference type in object creation. // x5 = new T5?(); // error 12 and 13 Diagnostic(ErrorCode.ERR_AnnotationDisallowedInObjectCreation, "new T5?()").WithArguments("T5").WithLocation(35, 14), @@ -22392,7 +22489,14 @@ void M() ", NonNullTypesTrue, NonNullTypesAttributesDefinition }); // PROTOTYPE(NullableReferenceTypes): should nullable reference types be disallowed in `typeof`? - c.VerifyDiagnostics(); + c.VerifyDiagnostics( + // (10,20): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // _ = typeof(T?); + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(10, 20), + // (13,25): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // _ = typeof(List); + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(13, 25) + ); } [Fact] @@ -22509,6 +22613,9 @@ static void F() // (6,9): warning CS8602: Possible dereference of a null reference. // s.ToString(); Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(6, 9), + // (7,25): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // var t = default(T?); + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(7, 25), // (8,9): warning CS8602: Possible dereference of a null reference. // t.ToString(); Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "t").WithLocation(8, 9)); @@ -27044,12 +27151,12 @@ void Test23(CL0.CL1 c, Action x23) options: TestOptions.ReleaseDll); c.VerifyDiagnostics( - // (15,21): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (15,27): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // void Test11(Action? x11) // 1 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "Action? x11").WithLocation(15, 21), - // (8,32): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(15, 27), + // (8,38): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // void Test21(CL0.CL1 c, Action? x21) // 4 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "Action? x21").WithLocation(8, 32), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(8, 38), // (17,18): warning CS8601: Possible null reference assignment. // E1 = x11; // 2 Diagnostic(ErrorCode.WRN_NullReferenceAssignment, "x11").WithLocation(17, 18), @@ -27083,9 +27190,9 @@ void Test23(CL0.CL1 c, Action x23) c1.VerifyDiagnostics(); var expectedDiagnostics = new[] { - // (8,32): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (8,38): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // void Test21(CL0.CL1 c, Action? x21) // 4 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "Action? x21").WithLocation(8, 32), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(8, 38), // (10,20): warning CS8601: Possible null reference assignment. // c.F1 = x21; // 5 Diagnostic(ErrorCode.WRN_NullReferenceAssignment, "x21").WithLocation(10, 20), @@ -27221,12 +27328,12 @@ void Test23(CL0.CL1 c, Action x23) options: TestOptions.ReleaseDll); c.VerifyDiagnostics( - // (13,21): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (13,27): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // void Test11(Action? x11) // 1 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "Action? x11").WithLocation(13, 21), - // (9,32): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(13, 27), + // (9,38): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // void Test21(CL0.CL1 c, Action? x21) // 4 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "Action? x21").WithLocation(9, 32), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(9, 38), // (15,18): warning CS8601: Possible null reference assignment. // E1 = x11; // 2 Diagnostic(ErrorCode.WRN_NullReferenceAssignment, "x11").WithLocation(15, 18), @@ -27261,9 +27368,9 @@ void Test23(CL0.CL1 c, Action x23) var expected = new[] { - // (9,32): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (9,38): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // void Test21(CL0.CL1 c, Action? x21) // 4 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "Action? x21").WithLocation(9, 32), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(9, 38), // (11,20): warning CS8601: Possible null reference assignment. // c.F1 = x21; // 5 Diagnostic(ErrorCode.WRN_NullReferenceAssignment, "x21").WithLocation(11, 20), @@ -27401,12 +27508,12 @@ void Test23(CL0.CL1 c, Action x23) options: TestOptions.ReleaseDll); c.VerifyDiagnostics( - // (13,21): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (13,27): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // void Test11(Action? x11) // 1 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "Action? x11").WithLocation(13, 21), - // (10,32): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(13, 27), + // (10,38): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // void Test21(CL0.CL1 c, Action? x21) // 4 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "Action? x21").WithLocation(10, 32), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(10, 38), // (15,18): warning CS8601: Possible null reference assignment. // E1 = x11; // 2 Diagnostic(ErrorCode.WRN_NullReferenceAssignment, "x11").WithLocation(15, 18), @@ -27441,9 +27548,9 @@ void Test23(CL0.CL1 c, Action x23) var expected = new[] { - // (10,32): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (10,38): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // void Test21(CL0.CL1 c, Action? x21) // 4 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "Action? x21").WithLocation(10, 32), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(10, 38), // (12,20): warning CS8601: Possible null reference assignment. // c.F1 = x21; // 5 Diagnostic(ErrorCode.WRN_NullReferenceAssignment, "x21").WithLocation(12, 20), @@ -27587,18 +27694,18 @@ void Test23(CL0.CL1 c, Action x23) options: TestOptions.ReleaseDll); c.VerifyDiagnostics( - // (13,24): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (13,22): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public Action? F2; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "F2").WithLocation(13, 24), - // (18,16): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(13, 22), + // (18,22): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public Action? P2 { get; set; } - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "Action?").WithLocation(18, 16), - // (23,16): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(18, 22), + // (23,22): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public Action? M2() { return null; } - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "Action?").WithLocation(23, 16), - // (13,30): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(23, 22), + // (13,28): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public event Action? E2; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "E2").WithLocation(13, 30), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(13, 28), // (30,19): warning CS8600: Converting null literal or possible null value to non-nullable type. // x13 = E2; // warn 1 Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "E2").WithLocation(30, 19), @@ -27618,15 +27725,15 @@ void Test23(CL0.CL1 c, Action x23) options: TestOptions.ReleaseDll); c1.VerifyDiagnostics( - // (13,24): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (13,22): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public Action? F2; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "F2").WithLocation(13, 24), - // (18,16): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(13, 22), + // (18,22): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public Action? P2 { get; set; } - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "Action?").WithLocation(18, 16), - // (23,16): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(18, 22), + // (23,22): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public Action? M2() { return null; } - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "Action?").WithLocation(23, 16) + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(23, 22) ); c = CreateCompilation(new[] { moduleAttributes, source2 }, new[] { c1.ToMetadataReference() }, @@ -30074,9 +30181,9 @@ static void G(string s) // (9,11): error CS8107: Feature 'static null checking' is not available in C# 7.0. Please use language version 8.0 or greater. // G(s!); // 11, 12 Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7, "s!").WithArguments("static null checking", "8.0").WithLocation(9, 11), - // (3,19): error CS8107: Feature 'static null checking' is not available in C# 7.0. Please use language version 8.0 or greater. + // (3,25): error CS8107: Feature 'static null checking' is not available in C# 7.0. Please use language version 8.0 or greater. // static void F(string? s) // 1 - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7, "string? s").WithArguments("static null checking", "8.0").WithLocation(3, 19), + Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7, "?").WithArguments("static null checking", "8.0").WithLocation(3, 25), // (5,15): warning CS8629: The suppression operator (!) should be used in code with a '[NonNullTypes(true/false)]' context. // G(null!); // 2, 3 Diagnostic(ErrorCode.WRN_MissingNonNullTypesContext, "!").WithLocation(5, 15), @@ -34991,12 +35098,13 @@ static void M(object x) }"; var comp = CreateEmptyCompilation(source); comp.VerifyDiagnostics( - // (6,24): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (6,22): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public object? F; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "F").WithLocation(6, 24), - // (11,16): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(6, 22), + // (11,22): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public object? P { get; set; } - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "object?").WithLocation(11, 16)); + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(11, 22) + ); var comp2 = CreateEmptyCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); comp2.VerifyDiagnostics( @@ -36775,9 +36883,9 @@ static void G2(I x2, I y2) new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }, parseOptions: TestOptions.Regular8); comp.VerifyDiagnostics( - // (4,20): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // (4,22): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // static T F1(I t) - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "I t").WithLocation(4, 20), + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(4, 22), // (10,12): warning CS8620: Nullability of reference types in argument of type 'I' doesn't match target type 'I' for parameter 't' in 'string C.F1(I t)'. // F1(x1).ToString(); // 1 Diagnostic(ErrorCode.WRN_NullabilityMismatchInArgument, "x1").WithArguments("I", "I", "t", "string C.F1(I t)").WithLocation(10, 12), @@ -38726,9 +38834,9 @@ static void F5(T t5) where T : I var comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); // PROTOTYPE(NullableReferenceTypes): Various differences from expected warnings. comp.VerifyDiagnostics( - // (29,39): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // (29,41): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // static void F5(T t5) where T : I - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "I").WithLocation(29, 39), + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(29, 41), // (11,14): warning CS8600: Converting null literal or possible null value to non-nullable type. // t1 = default; // 1 Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "default").WithLocation(11, 14), @@ -39020,13 +39128,13 @@ void F3(T3? t3) where T3 : class? comp.VerifyDiagnostics( // (9,31): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public static void F2(T2? t2) where T2 : class? - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T2? t2").WithLocation(9, 31), + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T2?").WithLocation(9, 31), // (6,27): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public static void F1(T1? t1) - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T1? t1").WithLocation(6, 27), + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T1?").WithLocation(6, 27), // (11,21): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // void F3(T3? t3) where T3 : class? - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T3? t3").WithLocation(11, 21) + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T3?").WithLocation(11, 21) ); } @@ -39053,10 +39161,10 @@ public static void F4(T42? t1) where T41 : B where T42 : T41? comp.VerifyDiagnostics( // (4,37): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public static void F1(T12? t1) where T11 : class where T12 : T11 - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T12? t1").WithLocation(4, 37), + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T12?").WithLocation(4, 37), // (13,37): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public static void F4(T42? t1) where T41 : B where T42 : T41? - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T42? t1").WithLocation(13, 37) + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T42?").WithLocation(13, 37) ); } @@ -39121,9 +39229,9 @@ class Node "; var comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); comp.VerifyDiagnostics( - // (10,44): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // (10,49): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public static void F3() where T3 : Node? - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "Node?").WithLocation(10, 44) + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T3?").WithLocation(10, 49) ); } @@ -39186,12 +39294,15 @@ class Node // (7,52): error CS0450: 'Node': cannot specify both a constraint class and the 'class' or 'struct' constraint // public static void F2() where T2 : class?, Node Diagnostic(ErrorCode.ERR_RefValBoundWithClass, "Node").WithArguments("Node").WithLocation(7, 52), + // (7,57): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // public static void F2() where T2 : class?, Node + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T2?").WithLocation(7, 57), // (10,52): error CS0450: 'Node': cannot specify both a constraint class and the 'class' or 'struct' constraint // public static void F3() where T3 : class?, Node? Diagnostic(ErrorCode.ERR_RefValBoundWithClass, "Node?").WithArguments("Node").WithLocation(10, 52), - // (10,52): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // (10,57): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public static void F3() where T3 : class?, Node? - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "Node?").WithLocation(10, 52), + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T3?").WithLocation(10, 57), // (4,52): error CS0450: 'Node': cannot specify both a constraint class and the 'class' or 'struct' constraint // public static void F1() where T1 : class?, Node? Diagnostic(ErrorCode.ERR_RefValBoundWithClass, "Node?").WithArguments("Node").WithLocation(4, 52) @@ -39220,12 +39331,12 @@ interface INode "; var comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); comp.VerifyDiagnostics( - // (7,44): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // (7,50): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public static void F2() where T2 : INode - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "INode").WithLocation(7, 44), - // (10,44): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T2?").WithLocation(7, 50), + // (10,50): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public static void F3() where T3 : INode? - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "INode?").WithLocation(10, 44) + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T3?").WithLocation(10, 50) ); } @@ -39276,9 +39387,9 @@ interface INode "; var comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); comp.VerifyDiagnostics( - // (10,52): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // (10,58): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public static void F3() where T3 : class?, INode? - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "INode?").WithLocation(10, 52) + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T3?").WithLocation(10, 58) ); } @@ -39310,15 +39421,15 @@ interface INode "; var comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); comp.VerifyDiagnostics( - // (10,83): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // (10,89): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public static void F3() where T31 : INode? where T32 : class?, T31, INode? - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "INode?").WithLocation(10, 83), + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T32?").WithLocation(10, 89), // (13,78): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public static void F4() where T41 : INode? where T42 : class?, T41?, INode? Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T41?").WithLocation(13, 78), - // (13,84): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // (13,90): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public static void F4() where T41 : INode? where T42 : class?, T41?, INode? - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "INode?").WithLocation(13, 84) + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T42?").WithLocation(13, 90) ); } @@ -39346,10 +39457,10 @@ interface INode comp.VerifyDiagnostics( // (7,37): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public static void F2(T22? t2) where T21 : INode? where T22 : class?, T21 - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T22? t2").WithLocation(7, 37), + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T22?").WithLocation(7, 37), // (10,37): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public static void F3(T32? t1) where T31 : INode where T32 : class?, T31? - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T32? t1").WithLocation(10, 37), + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T32?").WithLocation(10, 37), // (10,84): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public static void F3(T32? t1) where T31 : INode where T32 : class?, T31? Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T31?").WithLocation(10, 84) @@ -39882,12 +39993,12 @@ void symbolValidator(ModuleSymbol m) // (20,17): warning CS8633: Nullability in constraints for type parameter 'T552' of method 'B.F5()' doesn't match the constraints for type parameter 'T52' of interface method 'IA.F5()'. Consider using an explicit interface implementation instead. // public void F5() where T551 : class where T552 : C1 Diagnostic(ErrorCode.WRN_NullabilityMismatchInConstraintsOnImplicitImplementation, "F5").WithArguments("T552", "B.F5()", "T52", "IA.F5()").WithLocation(20, 17), - // (20,66): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // (20,69): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public void F5() where T551 : class where T552 : C1 - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "C1").WithLocation(20, 66), - // (51,70): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T551?").WithLocation(20, 69), + // (51,73): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public void F6() where T6661 : class where T6662 : C1 - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "C1").WithLocation(51, 70) + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T6661?").WithLocation(51, 73) ); var comp4 = CreateCompilation(new[] { source1 }); @@ -40540,12 +40651,12 @@ void symbolValidator(ModuleSymbol m) // (20,17): warning CS8633: Nullability in constraints for type parameter 'T552' of method 'B.F5()' doesn't match the constraints for type parameter 'T52' of interface method 'IA.F5()'. Consider using an explicit interface implementation instead. // public void F5() where T551 : class where T552 : C1 Diagnostic(ErrorCode.WRN_NullabilityMismatchInConstraintsOnImplicitImplementation, "F5").WithArguments("T552", "B.F5()", "T52", "IA.F5()").WithLocation(20, 17), - // (20,66): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // (20,69): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public void F5() where T551 : class where T552 : C1 - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "C1").WithLocation(20, 66), - // (51,70): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T551?").WithLocation(20, 69), + // (51,73): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public void F6() where T6661 : class where T6662 : C1 - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "C1").WithLocation(51, 70) + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T6661?").WithLocation(51, 73) ); var comp4 = CreateCompilation(new[] { source1 }); @@ -41460,6 +41571,1100 @@ void symbolValidator2(ModuleSymbol m) symbolValidator2(comp6.SourceModule); } + [Fact] + public void Constraints_46() + { + var source = +@" +class B +{ + public static void F1() where T1 : object + { + } + + public static void F2() where T2 : System.Object + { + } +}"; + var comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); + comp.VerifyDiagnostics( + ); + + CompileAndVerify(comp, sourceSymbolValidator: symbolValidator, symbolValidator: symbolValidator); + void symbolValidator(ModuleSymbol m) + { + var f1 = (MethodSymbol)m.GlobalNamespace.GetMember("B.F1"); + Assert.Equal("void B.F1() where T1 : System.Object", f1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + TypeParameterSymbol t1 = f1.TypeParameters[0]; + Assert.False(t1.IsReferenceType); + Assert.True(t1.IsNotNullableIfReferenceType); + Assert.Empty(t1.GetAttributes()); + + var f2 = (MethodSymbol)m.GlobalNamespace.GetMember("B.F2"); + Assert.Equal("void B.F2() where T2 : System.Object", f2.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + TypeParameterSymbol t2 = f2.TypeParameters[0]; + Assert.False(t2.IsReferenceType); + Assert.True(t2.IsNotNullableIfReferenceType); + Assert.Empty(t2.GetAttributes()); + } + } + + [Fact] + public void Constraints_47() + { + var source = +@" +class B +{ + public static void F1() where T1 : object + { + } + + public static void F2() where T2 : System.Object + { + } +}"; + var comp = CreateCompilation(new[] { source }); + comp.VerifyDiagnostics( + ); + + CompileAndVerify(comp, sourceSymbolValidator: symbolValidator, symbolValidator: symbolValidator); + void symbolValidator(ModuleSymbol m) + { + var f1 = (MethodSymbol)m.GlobalNamespace.GetMember("B.F1"); + Assert.Equal("void B.F1() where T1 : System.Object", f1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + TypeParameterSymbol t1 = f1.TypeParameters[0]; + Assert.False(t1.IsReferenceType); + Assert.Null(t1.IsNotNullableIfReferenceType); + Assert.Empty(t1.GetAttributes()); + + var f2 = (MethodSymbol)m.GlobalNamespace.GetMember("B.F2"); + Assert.Equal("void B.F2() where T2 : System.Object", f2.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + TypeParameterSymbol t2 = f2.TypeParameters[0]; + Assert.False(t2.IsReferenceType); + Assert.Null(t2.IsNotNullableIfReferenceType); + Assert.Empty(t2.GetAttributes()); + } + } + + [Fact] + public void Constraints_48() + { + var source = +@" +class B +{ + public static void F1(T1? t1) where T1 : object? + { + } + + public static void F2(T2? t2) where T2 : System.Object? + { + } +}"; + var comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); + comp.VerifyDiagnostics( + // (4,31): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // public static void F1(T1? t1) where T1 : object? + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T1?").WithLocation(4, 31), + // (4,50): error CS0702: Constraint cannot be special class 'object?' + // public static void F1(T1? t1) where T1 : object? + Diagnostic(ErrorCode.ERR_SpecialTypeAsBound, "object?").WithArguments("object?").WithLocation(4, 50), + // (8,31): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // public static void F2(T2? t2) where T2 : System.Object? + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T2?").WithLocation(8, 31), + // (8,50): error CS0702: Constraint cannot be special class 'object?' + // public static void F2(T2? t2) where T2 : System.Object? + Diagnostic(ErrorCode.ERR_SpecialTypeAsBound, "System.Object?").WithArguments("object?").WithLocation(8, 50) + ); + + var m = comp.SourceModule; + + var f1 = (MethodSymbol)m.GlobalNamespace.GetMember("B.F1"); + Assert.Equal("void B.F1(T1? t1)", f1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + TypeParameterSymbol t1 = f1.TypeParameters[0]; + Assert.False(t1.IsReferenceType); + Assert.False(t1.IsNotNullableIfReferenceType); + Assert.Empty(t1.GetAttributes()); + + var f2 = (MethodSymbol)m.GlobalNamespace.GetMember("B.F2"); + Assert.Equal("void B.F2(T2? t2)", f2.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + TypeParameterSymbol t2 = f2.TypeParameters[0]; + Assert.False(t2.IsReferenceType); + Assert.False(t2.IsNotNullableIfReferenceType); + Assert.Empty(t2.GetAttributes()); + } + + [Fact] + public void Constraints_49() + { + var source = +@" +class B +{ + public static void F1() where T1 : object + { + } + + public static void F2() where T2 : System.Object + { + } +}"; + var comp = CreateCompilation(new[] { source }, parseOptions: TestOptions.Regular7_3); + var expected = new[] + { + // (4,44): error CS8370: Feature 'object generic type constraint' is not available in C# 7.3. Please use language version 8.0 or greater. + // public static void F1() where T1 : object + Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "object").WithArguments("object generic type constraint", "8.0").WithLocation(4, 44), + // (8,44): error CS8370: Feature 'object generic type constraint' is not available in C# 7.3. Please use language version 8.0 or greater. + // public static void F2() where T2 : System.Object + Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "System.Object").WithArguments("object generic type constraint", "8.0").WithLocation(8, 44) + }; + + comp.VerifyDiagnostics(expected); + + { + var m = comp.SourceModule; + + var f1 = (MethodSymbol)m.GlobalNamespace.GetMember("B.F1"); + Assert.Equal("void B.F1() where T1 : System.Object", f1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + TypeParameterSymbol t1 = f1.TypeParameters[0]; + Assert.False(t1.IsReferenceType); + Assert.Null(t1.IsNotNullableIfReferenceType); + Assert.Empty(t1.GetAttributes()); + + var f2 = (MethodSymbol)m.GlobalNamespace.GetMember("B.F2"); + Assert.Equal("void B.F2() where T2 : System.Object", f2.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + TypeParameterSymbol t2 = f2.TypeParameters[0]; + Assert.False(t2.IsReferenceType); + Assert.Null(t2.IsNotNullableIfReferenceType); + Assert.Empty(t2.GetAttributes()); + } + + comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }, parseOptions: TestOptions.Regular7_3, skipUsesIsNullable: true); + + comp.VerifyDiagnostics(expected.Concat(new[] { + // (1,10): error CS8630: Please use language version 8.0 or greater to use the NonNullTypes attribute. + // [module: System.Runtime.CompilerServices.NonNullTypes(true)] + Diagnostic(ErrorCode.ERR_NonNullTypesNotAvailable, "System.Runtime.CompilerServices.NonNullTypes(true)").WithArguments("8.0").WithLocation(1, 10) + }).ToArray()); + + { + var m = comp.SourceModule; + + var f1 = (MethodSymbol)m.GlobalNamespace.GetMember("B.F1"); + Assert.Equal("void B.F1() where T1 : System.Object", f1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + TypeParameterSymbol t1 = f1.TypeParameters[0]; + Assert.False(t1.IsReferenceType); + Assert.True(t1.IsNotNullableIfReferenceType); + Assert.Empty(t1.GetAttributes()); + + var f2 = (MethodSymbol)m.GlobalNamespace.GetMember("B.F2"); + Assert.Equal("void B.F2() where T2 : System.Object", f2.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + TypeParameterSymbol t2 = f2.TypeParameters[0]; + Assert.False(t2.IsReferenceType); + Assert.True(t2.IsNotNullableIfReferenceType); + Assert.Empty(t2.GetAttributes()); + } + } + + [Fact] + public void Constraints_50() + { + var source = +@" +class B +{ + public static void F1(T1? t1) where T1 : object + { + } + + public static void F2(T2? t2) where T2 : System.Object + { + } +}"; + var comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); + comp.VerifyDiagnostics( + // (4,31): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // public static void F1(T1? t1) where T1 : object + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T1?").WithLocation(4, 31), + // (8,31): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // public static void F2(T2? t2) where T2 : System.Object + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T2?").WithLocation(8, 31) + ); + } + + [Fact] + public void Constraints_51() + { + var source = +@" +class B +{ + public static void F1(T1? t1) where T1 : struct, object + { + } + + public static void F2(T2? t2) where T2 : struct, System.Object + { + } +}"; + var comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); + comp.VerifyDiagnostics( + // (8,58): error CS0450: 'object': cannot specify both a constraint class and the 'class' or 'struct' constraint + // public static void F2(T2? t2) where T2 : struct, System.Object + Diagnostic(ErrorCode.ERR_RefValBoundWithClass, "System.Object").WithArguments("object").WithLocation(8, 58), + // (4,58): error CS0450: 'object': cannot specify both a constraint class and the 'class' or 'struct' constraint + // public static void F1(T1? t1) where T1 : struct, object + Diagnostic(ErrorCode.ERR_RefValBoundWithClass, "object").WithArguments("object").WithLocation(4, 58) + ); + + var m = comp.SourceModule; + + var f1 = (MethodSymbol)m.GlobalNamespace.GetMember("B.F1"); + Assert.Equal("void B.F1(T1? t1) where T1 : struct", f1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + TypeParameterSymbol t1 = f1.TypeParameters[0]; + Assert.True(t1.IsValueType); + Assert.False(t1.IsNotNullableIfReferenceType); + Assert.Empty(t1.GetAttributes()); + + var f2 = (MethodSymbol)m.GlobalNamespace.GetMember("B.F2"); + Assert.Equal("void B.F2(T2? t2) where T2 : struct", f2.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + TypeParameterSymbol t2 = f2.TypeParameters[0]; + Assert.True(t2.IsValueType); + Assert.False(t2.IsNotNullableIfReferenceType); + Assert.Empty(t2.GetAttributes()); + } + + [Fact] + public void Constraints_52() + { + var source = +@" +class B +{ + public static void F1(T1? t1) where T1 : class, object + { + } + + public static void F2(T2? t2) where T2 : class, System.Object + { + } +}"; + var comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); + comp.VerifyDiagnostics( + // (4,57): error CS0450: 'object': cannot specify both a constraint class and the 'class' or 'struct' constraint + // public static void F1(T1? t1) where T1 : class, object + Diagnostic(ErrorCode.ERR_RefValBoundWithClass, "object").WithArguments("object").WithLocation(4, 57), + // (8,57): error CS0450: 'object': cannot specify both a constraint class and the 'class' or 'struct' constraint + // public static void F2(T2? t2) where T2 : class, System.Object + Diagnostic(ErrorCode.ERR_RefValBoundWithClass, "System.Object").WithArguments("object").WithLocation(8, 57) + ); + + var m = comp.SourceModule; + + var f1 = (MethodSymbol)m.GlobalNamespace.GetMember("B.F1"); + Assert.Equal("void B.F1(T1? t1) where T1 : class", f1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + TypeParameterSymbol t1 = f1.TypeParameters[0]; + Assert.True(t1.IsReferenceType); + Assert.True(t1.IsNotNullableIfReferenceType); + Assert.Empty(t1.GetAttributes()); + + var f2 = (MethodSymbol)m.GlobalNamespace.GetMember("B.F2"); + Assert.Equal("void B.F2(T2? t2) where T2 : class", f2.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + TypeParameterSymbol t2 = f2.TypeParameters[0]; + Assert.True(t2.IsReferenceType); + Assert.True(t2.IsNotNullableIfReferenceType); + Assert.Empty(t2.GetAttributes()); + } + + [Fact] + public void Constraints_53() + { + var source = +@" +class B +{ + public static void F1(T1? t1) where T1 : class?, object + { + } + + public static void F2(T2? t2) where T2 : class?, System.Object + { + } +}"; + var comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); + + Assert.False(((MethodSymbol)comp.SourceModule.GlobalNamespace.GetMember("B.F1")).TypeParameters[0].IsNotNullableIfReferenceType); + + comp.VerifyDiagnostics( + // (4,31): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // public static void F1(T1? t1) where T1 : class?, object + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T1?").WithLocation(4, 31), + // (4,58): error CS0450: 'object': cannot specify both a constraint class and the 'class' or 'struct' constraint + // public static void F1(T1? t1) where T1 : class?, object + Diagnostic(ErrorCode.ERR_RefValBoundWithClass, "object").WithArguments("object").WithLocation(4, 58), + // (8,31): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // public static void F2(T2? t2) where T2 : class?, System.Object + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T2?").WithLocation(8, 31), + // (8,58): error CS0450: 'object': cannot specify both a constraint class and the 'class' or 'struct' constraint + // public static void F2(T2? t2) where T2 : class?, System.Object + Diagnostic(ErrorCode.ERR_RefValBoundWithClass, "System.Object").WithArguments("object").WithLocation(8, 58) + ); + + var m = comp.SourceModule; + + var f1 = (MethodSymbol)m.GlobalNamespace.GetMember("B.F1"); + Assert.Equal("void B.F1(T1? t1) where T1 : class?", f1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + TypeParameterSymbol t1 = f1.TypeParameters[0]; + Assert.True(t1.IsReferenceType); + Assert.False(t1.IsNotNullableIfReferenceType); + Assert.Empty(t1.GetAttributes()); + + var f2 = (MethodSymbol)m.GlobalNamespace.GetMember("B.F2"); + Assert.Equal("void B.F2(T2? t2) where T2 : class?", f2.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + TypeParameterSymbol t2 = f2.TypeParameters[0]; + Assert.True(t2.IsReferenceType); + Assert.False(t2.IsNotNullableIfReferenceType); + Assert.Empty(t2.GetAttributes()); + } + + [Fact] + public void Constraints_54() + { + var source = +@" +class B +{ + public static void F1(T1? t1) where T1 : class?, B + { + } +}"; + var comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); + + comp.VerifyDiagnostics( + // (4,31): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // public static void F1(T1? t1) where T1 : class?, B + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T1?").WithLocation(4, 31), + // (4,58): error CS0450: 'B': cannot specify both a constraint class and the 'class' or 'struct' constraint + // public static void F1(T1? t1) where T1 : class?, B + Diagnostic(ErrorCode.ERR_RefValBoundWithClass, "B").WithArguments("B").WithLocation(4, 58) + ); + + var m = comp.SourceModule; + + var f1 = (MethodSymbol)m.GlobalNamespace.GetMember("B.F1"); + Assert.Equal("void B.F1(T1? t1) where T1 : class?", f1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + TypeParameterSymbol t1 = f1.TypeParameters[0]; + Assert.True(t1.IsReferenceType); + Assert.False(t1.IsNotNullableIfReferenceType); + } + + [Fact] + public void Constraints_55() + { + var source = +@" +interface I +{ + void F1(TF1 x) where TF1 : TI; +} + +class A : I +{ + void I.F1(TF1A x) + {} +} + +class B : I +{ + void I.F1(TF1B x) + {} +} +"; + var comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); + comp.VerifyDiagnostics( + ); + + CompileAndVerify(comp, sourceSymbolValidator: symbolValidator, symbolValidator: symbolValidator); + void symbolValidator(ModuleSymbol m) + { + bool isSource = !(m is PEModuleSymbol); + + var af1 = (MethodSymbol)m.GlobalNamespace.GetMember("A.I.F1"); + Assert.Equal("I.F1", af1.Name); + Assert.Equal("I.F1", af1.MetadataName); + Assert.Equal("void A.I.F1(TF1A x) where TF1A : System.Object", af1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + TypeParameterSymbol at1 = af1.TypeParameters[0]; + Assert.False(at1.IsReferenceType); + Assert.True(at1.IsNotNullableIfReferenceType); + Assert.Empty(at1.GetAttributes()); + + Assert.Equal("void I.F1(TF1 x) where TF1 : System.Object", af1.ExplicitInterfaceImplementations.Single().ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + + var bf1 = (MethodSymbol)m.GlobalNamespace.GetMember("B.I.F1"); + Assert.Equal("I.F1", bf1.Name); + Assert.Equal("I.F1", bf1.MetadataName); + if (isSource) + { + Assert.Equal("void B.I.F1(TF1B x)", bf1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + } + else + { + Assert.Equal("void B.I.F1(TF1B x)", bf1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + } + + TypeParameterSymbol tf1 = bf1.TypeParameters[0]; + Assert.False(tf1.IsReferenceType); + Assert.False(tf1.IsNotNullableIfReferenceType); + Assert.Empty(tf1.GetAttributes()); + if (isSource) + { + Assert.Equal("void I.F1(TF1 x)", bf1.ExplicitInterfaceImplementations.Single().ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + } + else + { + Assert.Equal("void I.F1(TF1 x) where TF1 : System.Object", bf1.ExplicitInterfaceImplementations.Single().ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + } + } + } + + [Fact] + public void Constraints_56() + { + var source = +@" +interface I +{ + void F1(TF1 x) where TF1 : TI; +} + +class A : I +{ + void I.F1(TF1A x) + {} +} + +class B : I +{ + void I.F1(TF1B x) + {} +} +"; + var comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); + comp.VerifyDiagnostics( + ); + + CompileAndVerify(comp, sourceSymbolValidator: symbolValidator, symbolValidator: symbolValidator); + void symbolValidator(ModuleSymbol m) + { + bool isSource = !(m is PEModuleSymbol); + + var af1 = (MethodSymbol)m.GlobalNamespace.GetMember("A.I.F1"); + Assert.Equal("I.F1", af1.Name); + Assert.Equal("I.F1", af1.MetadataName); + Assert.Equal("void A.I.F1(TF1A x) where TF1A : A", af1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + TypeParameterSymbol at1 = af1.TypeParameters[0]; + Assert.True(at1.IsReferenceType); + Assert.True(at1.IsNotNullableIfReferenceType); + Assert.Empty(at1.GetAttributes()); + + Assert.Equal("void I.F1(TF1 x) where TF1 : A", af1.ExplicitInterfaceImplementations.Single().ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + + var bf1 = (MethodSymbol)m.GlobalNamespace.GetMember("B.I.F1"); + Assert.Equal("I.F1", bf1.Name); + Assert.Equal("I.F1", bf1.MetadataName); + if (isSource) + { + Assert.Equal("void B.I.F1(TF1B x) where TF1B : A?", bf1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + } + else + { + Assert.Equal("void B.I.F1(TF1B x) where TF1B : A?", bf1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + } + + TypeParameterSymbol tf1 = bf1.TypeParameters[0]; + Assert.True(tf1.IsReferenceType); + Assert.False(tf1.IsNotNullableIfReferenceType); + Assert.Empty(tf1.GetAttributes()); + if (isSource) + { + Assert.Equal("void I.F1(TF1 x) where TF1 : A?", bf1.ExplicitInterfaceImplementations.Single().ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + } + else + { + Assert.Equal("void I.F1(TF1 x) where TF1 : A", bf1.ExplicitInterfaceImplementations.Single().ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + } + } + } + + [Fact] + public void Constraints_57() + { + var source = +@" +interface I +{ + void F1(TF1 x) where TF1 : class?, TI; +} + +class A : I +{ + void I.F1(TF1A x) + {} +} + +class B : I +{ + void I.F1(TF1B x) + {} +} +"; + var comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); + comp.VerifyDiagnostics( + ); + + CompileAndVerify(comp, sourceSymbolValidator: symbolValidator, symbolValidator: symbolValidator); + void symbolValidator(ModuleSymbol m) + { + bool isSource = !(m is PEModuleSymbol); + + var af1 = (MethodSymbol)m.GlobalNamespace.GetMember("A.I.F1"); + Assert.Equal("I.F1", af1.Name); + Assert.Equal("I.F1", af1.MetadataName); + Assert.Equal("void A.I.F1(TF1A x) where TF1A : class?, System.Object", af1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + TypeParameterSymbol at1 = af1.TypeParameters[0]; + Assert.True(at1.IsReferenceType); + Assert.True(at1.IsNotNullableIfReferenceType); + + Assert.Equal("void I.F1(TF1 x) where TF1 : class?, System.Object", af1.ExplicitInterfaceImplementations.Single().ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + + var bf1 = (MethodSymbol)m.GlobalNamespace.GetMember("B.I.F1"); + Assert.Equal("I.F1", bf1.Name); + Assert.Equal("I.F1", bf1.MetadataName); + if (isSource) + { + Assert.Equal("void B.I.F1(TF1B x) where TF1B : class?", bf1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + } + else + { + Assert.Equal("void B.I.F1(TF1B x) where TF1B : class?", bf1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + } + + TypeParameterSymbol tf1 = bf1.TypeParameters[0]; + Assert.True(tf1.IsReferenceType); + Assert.False(tf1.IsNotNullableIfReferenceType); + if (isSource) + { + Assert.Equal("void I.F1(TF1 x) where TF1 : class?", bf1.ExplicitInterfaceImplementations.Single().ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + } + else + { + Assert.Equal("void I.F1(TF1 x) where TF1 : class?, System.Object", bf1.ExplicitInterfaceImplementations.Single().ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + } + } + } + + [Fact] + public void Constraints_58() + { + var source = +@" +class B +{ + public static void F1(T1? t1) where T1 : B, object + { + } +}"; + var comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); + comp.VerifyDiagnostics( + // (4,53): error CS0406: The class type constraint 'object' must come before any other constraints + // public static void F1(T1? t1) where T1 : B, object + Diagnostic(ErrorCode.ERR_ClassBoundNotFirst, "object").WithArguments("object").WithLocation(4, 53) + ); + + var m = comp.SourceModule; + + var f1 = (MethodSymbol)m.GlobalNamespace.GetMember("B.F1"); + Assert.Equal("void B.F1(T1? t1) where T1 : B", f1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + TypeParameterSymbol t1 = f1.TypeParameters[0]; + Assert.True(t1.IsReferenceType); + Assert.True(t1.IsNotNullableIfReferenceType); + } + + [Fact] + public void Constraints_59() + { + var source = +@" +class B +{ + public static void F1(T1? t1) where T1 : B?, object + { + } +}"; + var comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); + comp.VerifyDiagnostics( + // (4,31): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // public static void F1(T1? t1) where T1 : B?, object + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T1?").WithLocation(4, 31), + // (4,54): error CS0406: The class type constraint 'object' must come before any other constraints + // public static void F1(T1? t1) where T1 : B?, object + Diagnostic(ErrorCode.ERR_ClassBoundNotFirst, "object").WithArguments("object").WithLocation(4, 54) + ); + + var m = comp.SourceModule; + + var f1 = (MethodSymbol)m.GlobalNamespace.GetMember("B.F1"); + Assert.Equal("void B.F1(T1? t1) where T1 : B?", f1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + TypeParameterSymbol t1 = f1.TypeParameters[0]; + Assert.True(t1.IsReferenceType); + Assert.False(t1.IsNotNullableIfReferenceType); + } + + [Fact] + public void Constraints_60() + { + var source = +@" +class B +{ + public static void F1(T1? t1) where T1 : object, B + { + } +}"; + var comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); + comp.VerifyDiagnostics( + // (4,31): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // public static void F1(T1? t1) where T1 : object, B + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T1?").WithLocation(4, 31), + // (4,58): error CS0406: The class type constraint 'B' must come before any other constraints + // public static void F1(T1? t1) where T1 : object, B + Diagnostic(ErrorCode.ERR_ClassBoundNotFirst, "B").WithArguments("B").WithLocation(4, 58) + ); + + var m = comp.SourceModule; + + var f1 = (MethodSymbol)m.GlobalNamespace.GetMember("B.F1"); + Assert.Equal("void B.F1(T1? t1) where T1 : System.Object", f1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + TypeParameterSymbol t1 = f1.TypeParameters[0]; + Assert.False(t1.IsReferenceType); + Assert.True(t1.IsNotNullableIfReferenceType); + } + + [Fact] + public void Constraints_61() + { + var source = +@" +class B +{ + public static void F1(T1? t1) where T1 : object?, B + { + } +}"; + var comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); + comp.VerifyDiagnostics( + // (4,50): error CS0702: Constraint cannot be special class 'object?' + // public static void F1(T1? t1) where T1 : object?, B + Diagnostic(ErrorCode.ERR_SpecialTypeAsBound, "object?").WithArguments("object?").WithLocation(4, 50) + ); + + var m = comp.SourceModule; + + var f1 = (MethodSymbol)m.GlobalNamespace.GetMember("B.F1"); + Assert.Equal("void B.F1(T1? t1) where T1 : B", f1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + TypeParameterSymbol t1 = f1.TypeParameters[0]; + Assert.True(t1.IsReferenceType); + Assert.True(t1.IsNotNullableIfReferenceType); + } + + [Fact] + public void Constraints_62() + { + var source = +@" +interface I +{ + void F1(TF1 x) where TF1 : B?, TI; +} + +class A : I +{ + void I.F1(TF1A x) + {} +} + +class B : I +{ + void I.F1(TF1B x) + {} +} +"; + var comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); + comp.VerifyDiagnostics( + ); + + CompileAndVerify(comp, sourceSymbolValidator: symbolValidator, symbolValidator: symbolValidator); + void symbolValidator(ModuleSymbol m) + { + bool isSource = !(m is PEModuleSymbol); + + var af1 = (MethodSymbol)m.GlobalNamespace.GetMember("A.I.F1"); + Assert.Equal("I.F1", af1.Name); + Assert.Equal("I.F1", af1.MetadataName); + Assert.Equal("void A.I.F1(TF1A x) where TF1A : B?, System.Object", af1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + TypeParameterSymbol at1 = af1.TypeParameters[0]; + Assert.True(at1.IsReferenceType); + Assert.True(at1.IsNotNullableIfReferenceType); + + Assert.Equal("void I.F1(TF1 x) where TF1 : B?, System.Object", af1.ExplicitInterfaceImplementations.Single().ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + + var bf1 = (MethodSymbol)m.GlobalNamespace.GetMember("B.I.F1"); + Assert.Equal("I.F1", bf1.Name); + Assert.Equal("I.F1", bf1.MetadataName); + if (isSource) + { + Assert.Equal("void B.I.F1(TF1B x) where TF1B : B?", bf1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + } + else + { + Assert.Equal("void B.I.F1(TF1B x) where TF1B : B?", bf1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + } + + TypeParameterSymbol tf1 = bf1.TypeParameters[0]; + Assert.True(tf1.IsReferenceType); + Assert.False(tf1.IsNotNullableIfReferenceType); + if (isSource) + { + Assert.Equal("void I.F1(TF1 x) where TF1 : B?", bf1.ExplicitInterfaceImplementations.Single().ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + } + else + { + Assert.Equal("void I.F1(TF1 x) where TF1 : B?, System.Object", bf1.ExplicitInterfaceImplementations.Single().ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + } + } + } + + [Fact] + public void Constraints_63() + { + var source = +@" +interface I +{ + void F1(TF1 x) where TF1 : TI1, TI2; +} + +class A : I +{ + void I.F1(TF1A x) + {} +} + +class B : I +{ + void I.F1(TF1B x) + {} +} +"; + var comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); + comp.VerifyDiagnostics( + ); + + CompileAndVerify(comp, sourceSymbolValidator: symbolValidator, symbolValidator: symbolValidator); + void symbolValidator(ModuleSymbol m) + { + bool isSource = !(m is PEModuleSymbol); + + var af1 = (MethodSymbol)m.GlobalNamespace.GetMember("A.I.F1"); + Assert.Equal("I.F1", af1.Name); + Assert.Equal("I.F1", af1.MetadataName); + if (isSource) + { + Assert.Equal("void A.I.F1(TF1A x) where TF1A : System.Object, B?", af1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + } + else + { + Assert.Equal("void A.I.F1(TF1A x) where TF1A : System.Object, B?", af1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + } + + TypeParameterSymbol at1 = af1.TypeParameters[0]; + Assert.True(at1.IsReferenceType); + Assert.True(at1.IsNotNullableIfReferenceType); + + if (isSource) + { + Assert.Equal("void I.F1(TF1 x) where TF1 : System.Object, B?", af1.ExplicitInterfaceImplementations.Single().ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + } + else + { + Assert.Equal("void I.F1(TF1 x) where TF1 : System.Object, B", af1.ExplicitInterfaceImplementations.Single().ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + } + + var bf1 = (MethodSymbol)m.GlobalNamespace.GetMember("B.I.F1"); + Assert.Equal("I.F1", bf1.Name); + Assert.Equal("I.F1", bf1.MetadataName); + if (isSource) + { + Assert.Equal("void B.I.F1(TF1B x) where TF1B : B?", bf1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + } + else + { + Assert.Equal("void B.I.F1(TF1B x) where TF1B : B?", bf1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + } + + TypeParameterSymbol tf1 = bf1.TypeParameters[0]; + Assert.True(tf1.IsReferenceType); + Assert.False(tf1.IsNotNullableIfReferenceType); + if (isSource) + { + Assert.Equal("void I.F1(TF1 x) where TF1 : B?", bf1.ExplicitInterfaceImplementations.Single().ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + } + else + { + Assert.Equal("void I.F1(TF1 x) where TF1 : System.Object, B", bf1.ExplicitInterfaceImplementations.Single().ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + } + } + } + + [Fact] + public void Constraints_64() + { + var source = +@" +interface I1 +{ + void F1(); + void F2() where TF2 : object; + void F3() where TF3 : object; + void F4() where TF4 : I3; + void F5() where TF5 : I3; + void F6() where TF6 : I3?; + void F7() where TF7 : object, I3; + void F8() where TF8 : object, I3; + void F9() where TF9 : object, I3; + void F10() where TF10 : object, I3?; + void F11() where TF11 : object, I3?; + void F12() where TF12 : object, I3?; + void F13() where TF13 : object, I3?; +} + +public interface I3 +{ +} + +class A : I1 +{ + public void F1() where TF1A : object + {} + public void F2() + {} + public void F3() where TF3A : object + {} + public void F4() where TF4A : object, I3 + {} + public void F5() where TF5A : object, I3? + {} + public void F6() where TF6A : object, I3? + {} + public void F7() where TF7A : I3 + {} + public void F8() where TF8A : I3? + {} + public void F9() where TF9A : object, I3 + {} + public void F10() where TF10A : I3 + {} + public void F11() where TF11A : I3? + {} + public void F12() where TF12A : object, I3 + {} + public void F13() where TF13A : object, I3? + {} +} +"; + var comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); + comp.VerifyDiagnostics( + // (25,17): warning CS8633: Nullability in constraints for type parameter 'TF1A' of method 'A.F1()' doesn't match the constraints for type parameter 'TF1' of interface method 'I1.F1()'. Consider using an explicit interface implementation instead. + // public void F1() where TF1A : object + Diagnostic(ErrorCode.WRN_NullabilityMismatchInConstraintsOnImplicitImplementation, "F1").WithArguments("TF1A", "A.F1()", "TF1", "I1.F1()").WithLocation(25, 17), + // (27,17): warning CS8633: Nullability in constraints for type parameter 'TF2A' of method 'A.F2()' doesn't match the constraints for type parameter 'TF2' of interface method 'I1.F2()'. Consider using an explicit interface implementation instead. + // public void F2() + Diagnostic(ErrorCode.WRN_NullabilityMismatchInConstraintsOnImplicitImplementation, "F2").WithArguments("TF2A", "A.F2()", "TF2", "I1.F2()").WithLocation(27, 17), + // (35,17): warning CS8633: Nullability in constraints for type parameter 'TF6A' of method 'A.F6()' doesn't match the constraints for type parameter 'TF6' of interface method 'I1.F6()'. Consider using an explicit interface implementation instead. + // public void F6() where TF6A : object, I3? + Diagnostic(ErrorCode.WRN_NullabilityMismatchInConstraintsOnImplicitImplementation, "F6").WithArguments("TF6A", "A.F6()", "TF6", "I1.F6()").WithLocation(35, 17), + // (39,17): warning CS8633: Nullability in constraints for type parameter 'TF8A' of method 'A.F8()' doesn't match the constraints for type parameter 'TF8' of interface method 'I1.F8()'. Consider using an explicit interface implementation instead. + // public void F8() where TF8A : I3? + Diagnostic(ErrorCode.WRN_NullabilityMismatchInConstraintsOnImplicitImplementation, "F8").WithArguments("TF8A", "A.F8()", "TF8", "I1.F8()").WithLocation(39, 17), + // (45,17): warning CS8633: Nullability in constraints for type parameter 'TF11A' of method 'A.F11()' doesn't match the constraints for type parameter 'TF11' of interface method 'I1.F11()'. Consider using an explicit interface implementation instead. + // public void F11() where TF11A : I3? + Diagnostic(ErrorCode.WRN_NullabilityMismatchInConstraintsOnImplicitImplementation, "F11").WithArguments("TF11A", "A.F11()", "TF11", "I1.F11()").WithLocation(45, 17) + ); + } + + [Fact] + public void Constraints_65() + { + var source = +@" +[System.Runtime.CompilerServices.NonNullTypes(false)] +interface I1 +{ + void F1(); + void F2() where TF2 : object; + void F3() where TF3 : object; + void F4() where TF4 : I3; + void F5() where TF5 : I3; + void F7() where TF7 : object, I3; + void F8() where TF8 : object, I3; + void F9() where TF9 : object, I3; +} + +public interface I3 +{ +} + +class A : I1 +{ + public void F1() where TF1A : object + {} + public void F2() + {} + public void F3() where TF3A : object + {} + public void F4() where TF4A : object, I3 + {} + public void F5() where TF5A : object, I3? + {} + public void F7() where TF7A : I3 + {} + public void F8() where TF8A : I3? + {} + public void F9() where TF9A : object, I3 + {} +} +"; + var comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); + // PROTOTYPE(NullableReferenceTypes): unexpected warning + comp.VerifyDiagnostics( + // (21,17): warning CS8633: Nullability in constraints for type parameter 'TF1A' of method 'A.F1()' doesn't match the constraints for type parameter 'TF1' of interface method 'I1.F1()'. Consider using an explicit interface implementation instead. + // public void F1() where TF1A : object + Diagnostic(ErrorCode.WRN_NullabilityMismatchInConstraintsOnImplicitImplementation, "F1").WithArguments("TF1A", "A.F1()", "TF1", "I1.F1()").WithLocation(21, 17) + ); + } + + [Fact] + public void Constraints_66() + { + var source = +@" +interface I1 +{ + void F1(); + void F2() where TF2 : object; + void F3() where TF3 : object; + void F4() where TF4 : I3; + void F7() where TF7 : object, I3; + void F9() where TF9 : object, I3; + void F10() where TF10 : object, I3?; + void F12() where TF12 : object, I3?; +} + +public interface I3 +{ +} + +[System.Runtime.CompilerServices.NonNullTypes(false)] +class A : I1 +{ + public void F1() where TF1A : object + {} + public void F2() + {} + public void F3() where TF3A : object + {} + public void F4() where TF4A : object, I3 + {} + public void F7() where TF7A : I3 + {} + public void F9() where TF9A : object, I3 + {} + public void F10() where TF10A : I3 + {} + public void F12() where TF12A : object, I3 + {} +} +"; + var comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); + // PROTOTYPE(NullableReferenceTypes): unexpected warning + comp.VerifyDiagnostics( + // (23,17): warning CS8633: Nullability in constraints for type parameter 'TF2A' of method 'A.F2()' doesn't match the constraints for type parameter 'TF2' of interface method 'I1.F2()'. Consider using an explicit interface implementation instead. + // public void F2() + Diagnostic(ErrorCode.WRN_NullabilityMismatchInConstraintsOnImplicitImplementation, "F2").WithArguments("TF2A", "A.F2()", "TF2", "I1.F2()").WithLocation(23, 17) + ); + } + + [Fact] + public void Constraints_67() + { + var source = +@" +class A +{ + public void F1(object x1, TF1 y1, TF1 z1 ) where TF1 : object + { + y1.ToString(); + x1 = z1; + } + + public void F2(object x2, TF2 y2, TF2 z2 ) where TF2 : class + { + y2.ToString(); + x2 = z2; + } + + public void F3(object x3, TF3 y3, TF3 z3 ) where TF3 : class? + { + y3.ToString(); + x3 = z3; + } +} +"; + var comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); + comp.VerifyDiagnostics( + // (18,9): warning CS8602: Possible dereference of a null reference. + // y3.ToString(); + Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "y3").WithLocation(18, 9), + // (19,14): warning CS8600: Converting null literal or possible null value to non-nullable type. + // x3 = z3; + Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "z3").WithLocation(19, 14) + ); + } + + [Fact] + public void UnconstrainedTypeParameter_Local() + { + var source = +@" +#pragma warning disable CS0168 +class B +{ + public static void F1() + { + T1? x; + } +}"; + var comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); + + comp.VerifyDiagnostics( + // (7,9): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // T1? x; + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T1?").WithLocation(7, 9) + ); + } + [Fact] public void ConstraintsChecks_01() { @@ -42744,25 +43949,349 @@ public interface IC } [Fact] - public void ConstraintsChecks_24() + public void ConstraintsChecks_24() + { + var source = +@" +class B where TB1 : A?, IB, IC? +{ [System.Runtime.CompilerServices.NonNullTypes(false)] + public void M1(TM1 x, TM2 y) where TM2 : TM1 + {} + + public void Test2(TB1? a2, TB1 b2) + { + M1(b2, a2); // 1 + M1(b2, a2); // 2 + } +} + +public class A +{} + +public interface IB +{} + +public interface IC +{} +"; + var comp1 = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); + + comp1.VerifyDiagnostics( + // (9,9): warning CS8631: The type 'TB1?' cannot be used as type parameter 'TM2' in the generic type or method 'B.M1(TM1, TM2)'. Nullability of type argument 'TB1?' doesn't match constraint type 'TB1'. + // M1(b2, a2); // 1 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "M1").WithArguments("B.M1(TM1, TM2)", "TB1", "TM2", "TB1?").WithLocation(9, 9), + // (10,9): warning CS8631: The type 'TB1?' cannot be used as type parameter 'TM2' in the generic type or method 'B.M1(TM1, TM2)'. Nullability of type argument 'TB1?' doesn't match constraint type 'TB1'. + // M1(b2, a2); // 2 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "M1").WithArguments("B.M1(TM1, TM2)", "TB1", "TM2", "TB1?").WithLocation(10, 9) + ); + } + + [Fact] + public void ConstraintsChecks_25() { var source = @" -class B where TB1 : A?, IB, IC? -{ [System.Runtime.CompilerServices.NonNullTypes(false)] - public void M1(TM1 x, TM2 y) where TM2 : TM1 +#pragma warning disable CS0168 + +public interface IA where TA : object +{ +} + +public interface IB : IA // 1 +{} + +public interface IC : IA +{} + +class B +{ + public void Test1() + { + IA x1; // 2 + IA z1; + } + + public void M1(TM1 x) where TM1: object {} - public void Test2(TB1? a2, TB1 b2) + public void Test2(string? a2, string b2) { - M1(b2, a2); // 1 - M1(b2, a2); // 2 + M1(a2); // 3 + M1(b2); + M1(a2); // 4 + M1(b2); // 5 + M1(b2); } + } +"; + var comp1 = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); + // https://github.com/dotnet/roslyn/issues/29678: Constraint violations are not reported for type references outside of method bodies. + comp1.VerifyDiagnostics( + // (18,12): warning CS8631: The type 'string?' cannot be used as type parameter 'TA' in the generic type or method 'IA'. Nullability of type argument 'string?' doesn't match constraint type 'object'. + // IA x1; // 2 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "string?").WithArguments("IA", "object", "TA", "string?").WithLocation(18, 12), + // (27,9): warning CS8631: The type 'string?' cannot be used as type parameter 'TM1' in the generic type or method 'B.M1(TM1)'. Nullability of type argument 'string?' doesn't match constraint type 'object'. + // M1(a2); // 3 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "M1").WithArguments("B.M1(TM1)", "object", "TM1", "string?").WithLocation(27, 9), + // (29,9): warning CS8631: The type 'string?' cannot be used as type parameter 'TM1' in the generic type or method 'B.M1(TM1)'. Nullability of type argument 'string?' doesn't match constraint type 'object'. + // M1(a2); // 4 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "M1").WithArguments("B.M1(TM1)", "object", "TM1", "string?").WithLocation(29, 9), + // (30,9): warning CS8631: The type 'string?' cannot be used as type parameter 'TM1' in the generic type or method 'B.M1(TM1)'. Nullability of type argument 'string?' doesn't match constraint type 'object'. + // M1(b2); // 5 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "M1").WithArguments("B.M1(TM1)", "object", "TM1", "string?").WithLocation(30, 9) + ); + } -public class A + [Fact] + public void ConstraintsChecks_26() + { + var source = +@" +#pragma warning disable CS0168 +[System.Runtime.CompilerServices.NonNullTypes(false)] +public interface IA where TA : object +{ +} + +public interface IB : IA {} +public interface IC : IA +{} + +class B +{ + public void Test1() + { + IA x1; + IA z1; + } + [System.Runtime.CompilerServices.NonNullTypes(false)] + public void M1(TM1 x) where TM1: object + {} + + public void Test2(string? a2, string b2) + { + M1(a2); + M1(b2); + M1(a2); + M1(b2); + M1(b2); + } + +} +"; + var comp1 = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); + comp1.VerifyDiagnostics( + ); + } + + [Fact] + public void ConstraintsChecks_27() + { + var source = +@" +#pragma warning disable CS0168 + +public interface IA where TA : object +{ +} +[System.Runtime.CompilerServices.NonNullTypes(false)] +public interface IB : IA where TIB : C? // 1 +{} +[System.Runtime.CompilerServices.NonNullTypes(false)] +public interface IC : IA where TIC : C // 2 +{} + +public class C +{} +[System.Runtime.CompilerServices.NonNullTypes(false)] +class B where TB1 : C? where TB2 : C +{ [System.Runtime.CompilerServices.NonNullTypes(true)] + public void Test1() + { + IA x1; // 3 + IA z1; // 4 + } + [System.Runtime.CompilerServices.NonNullTypes(true)] + public void M1(TM1 x) where TM1: object + {} + [System.Runtime.CompilerServices.NonNullTypes(true)] + public void Test2(TB1 a2, TB2 b2) + { + M1(a2); // 5 + M1(b2); // 6 + M1(a2); // 7 + M1(b2); // 8 + } +} +"; + var comp1 = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); + // https://github.com/dotnet/roslyn/issues/29678: Constraint violations are not reported for type references outside of method bodies. + comp1.GetDiagnostics().Where(d => d.Code != (int)ErrorCode.WRN_MissingNonNullTypesContextForAnnotation).Verify( + // (21,12): warning CS8631: The type 'TB1' cannot be used as type parameter 'TA' in the generic type or method 'IA'. Nullability of type argument 'TB1' doesn't match constraint type 'object'. + // IA x1; // 3 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "TB1").WithArguments("IA", "object", "TA", "TB1").WithLocation(21, 12), + // (22,12): warning CS8631: The type 'TB2' cannot be used as type parameter 'TA' in the generic type or method 'IA'. Nullability of type argument 'TB2' doesn't match constraint type 'object'. + // IA z1; // 4 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "TB2").WithArguments("IA", "object", "TA", "TB2").WithLocation(22, 12), + // (30,9): warning CS8631: The type 'TB1' cannot be used as type parameter 'TM1' in the generic type or method 'B.M1(TM1)'. Nullability of type argument 'TB1' doesn't match constraint type 'object'. + // M1(a2); // 5 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "M1").WithArguments("B.M1(TM1)", "object", "TM1", "TB1").WithLocation(30, 9), + // (31,9): warning CS8631: The type 'TB2' cannot be used as type parameter 'TM1' in the generic type or method 'B.M1(TM1)'. Nullability of type argument 'TB2' doesn't match constraint type 'object'. + // M1(b2); // 6 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "M1").WithArguments("B.M1(TM1)", "object", "TM1", "TB2").WithLocation(31, 9), + // (32,9): warning CS8631: The type 'TB1' cannot be used as type parameter 'TM1' in the generic type or method 'B.M1(TM1)'. Nullability of type argument 'TB1' doesn't match constraint type 'object'. + // M1(a2); // 7 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "M1").WithArguments("B.M1(TM1)", "object", "TM1", "TB1").WithLocation(32, 9), + // (33,9): warning CS8631: The type 'TB2' cannot be used as type parameter 'TM1' in the generic type or method 'B.M1(TM1)'. Nullability of type argument 'TB2' doesn't match constraint type 'object'. + // M1(b2); // 8 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "M1").WithArguments("B.M1(TM1)", "object", "TM1", "TB2").WithLocation(33, 9) + ); + } + + [Fact] + public void ConstraintsChecks_28() + { + var source = +@" +#pragma warning disable CS0168 + +public interface IA where TA : object +{ +} + +public interface IB : IA // 1 +{} + +public interface IC : IA where TIC : object +{} + +class B where TB2 : object +{ + public void Test1() + { + IA x1; // 2 + IA z1; + } + + public void M1(TM1 x) where TM1: object + {} + + public void Test2(TB1 a2, TB2 b2) + { + M1(a2); // 3 + M1(b2); + M1(a2); // 4 + M1(b2); + } +} +"; + var comp1 = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); + // https://github.com/dotnet/roslyn/issues/29678: Constraint violations are not reported for type references outside of method bodies. + comp1.VerifyDiagnostics( + // (18,12): warning CS8631: The type 'TB1' cannot be used as type parameter 'TA' in the generic type or method 'IA'. Nullability of type argument 'TB1' doesn't match constraint type 'object'. + // IA x1; // 2 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "TB1").WithArguments("IA", "object", "TA", "TB1").WithLocation(18, 12), + // (27,9): warning CS8631: The type 'TB1' cannot be used as type parameter 'TM1' in the generic type or method 'B.M1(TM1)'. Nullability of type argument 'TB1' doesn't match constraint type 'object'. + // M1(a2); // 3 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "M1").WithArguments("B.M1(TM1)", "object", "TM1", "TB1").WithLocation(27, 9), + // (29,9): warning CS8631: The type 'TB1' cannot be used as type parameter 'TM1' in the generic type or method 'B.M1(TM1)'. Nullability of type argument 'TB1' doesn't match constraint type 'object'. + // M1(a2); // 4 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "M1").WithArguments("B.M1(TM1)", "object", "TM1", "TB1").WithLocation(29, 9) + ); + } + + [Fact] + public void ConstraintsChecks_29() + { + var source = +@" +#pragma warning disable CS0168 + +public interface IA where TA : object +{ +} +[System.Runtime.CompilerServices.NonNullTypes(false)] +public interface IB : IA // 1 +{} +[System.Runtime.CompilerServices.NonNullTypes(false)] +public interface IC : IA where TIC : object // 2 +{} +[System.Runtime.CompilerServices.NonNullTypes(false)] +class B where TB2 : object +{ [System.Runtime.CompilerServices.NonNullTypes(true)] + public void Test1() + { + IA x1; // 3 + IA z1; // 4 + } + [System.Runtime.CompilerServices.NonNullTypes(true)] + public void M1(TM1 x) where TM1: object + {} + [System.Runtime.CompilerServices.NonNullTypes(true)] + public void Test2(TB1 a2, TB2 b2) + { + M1(a2); // 5 + M1(b2); // 6 + M1(a2); // 7 + M1(b2); // 8 + } +} +"; + var comp1 = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); + // https://github.com/dotnet/roslyn/issues/29678: Constraint violations are not reported for type references outside of method bodies. + comp1.GetDiagnostics().Where(d => d.Code != (int)ErrorCode.WRN_MissingNonNullTypesContextForAnnotation).Verify( + // (18,12): warning CS8631: The type 'TB1' cannot be used as type parameter 'TA' in the generic type or method 'IA'. Nullability of type argument 'TB1' doesn't match constraint type 'object'. + // IA x1; // 3 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "TB1").WithArguments("IA", "object", "TA", "TB1").WithLocation(18, 12), + // (19,12): warning CS8631: The type 'TB2' cannot be used as type parameter 'TA' in the generic type or method 'IA'. Nullability of type argument 'TB2' doesn't match constraint type 'object'. + // IA z1; // 4 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "TB2").WithArguments("IA", "object", "TA", "TB2").WithLocation(19, 12), + // (27,9): warning CS8631: The type 'TB1' cannot be used as type parameter 'TM1' in the generic type or method 'B.M1(TM1)'. Nullability of type argument 'TB1' doesn't match constraint type 'object'. + // M1(a2); // 5 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "M1").WithArguments("B.M1(TM1)", "object", "TM1", "TB1").WithLocation(27, 9), + // (28,9): warning CS8631: The type 'TB2' cannot be used as type parameter 'TM1' in the generic type or method 'B.M1(TM1)'. Nullability of type argument 'TB2' doesn't match constraint type 'object'. + // M1(b2); // 6 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "M1").WithArguments("B.M1(TM1)", "object", "TM1", "TB2").WithLocation(28, 9), + // (29,9): warning CS8631: The type 'TB1' cannot be used as type parameter 'TM1' in the generic type or method 'B.M1(TM1)'. Nullability of type argument 'TB1' doesn't match constraint type 'object'. + // M1(a2); // 7 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "M1").WithArguments("B.M1(TM1)", "object", "TM1", "TB1").WithLocation(29, 9), + // (30,9): warning CS8631: The type 'TB2' cannot be used as type parameter 'TM1' in the generic type or method 'B.M1(TM1)'. Nullability of type argument 'TB2' doesn't match constraint type 'object'. + // M1(b2); // 8 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "M1").WithArguments("B.M1(TM1)", "object", "TM1", "TB2").WithLocation(30, 9) + ); + } + + [Fact] + public void ConstraintsChecks_30() + { + var source = +@" +#pragma warning disable CS0168 + +public interface IA where TA : object, IB, IC +{ +} + +class B where TB1 : IB?, IC? +{ + public void Test1() + { + IA x1; // 1 + } + + public void M1(TM1 x) where TM1: object, IB, IC + {} + + public void Test2(TB1 a2) + { + M1(a2); // 2 + M1(a2); // 3 + } +} + public interface IB {} @@ -42772,12 +44301,33 @@ public interface IC var comp1 = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); comp1.VerifyDiagnostics( - // (9,9): warning CS8631: The type 'TB1?' cannot be used as type parameter 'TM2' in the generic type or method 'B.M1(TM1, TM2)'. Nullability of type argument 'TB1?' doesn't match constraint type 'TB1'. - // M1(b2, a2); // 1 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "M1").WithArguments("B.M1(TM1, TM2)", "TB1", "TM2", "TB1?").WithLocation(9, 9), - // (10,9): warning CS8631: The type 'TB1?' cannot be used as type parameter 'TM2' in the generic type or method 'B.M1(TM1, TM2)'. Nullability of type argument 'TB1?' doesn't match constraint type 'TB1'. - // M1(b2, a2); // 2 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "M1").WithArguments("B.M1(TM1, TM2)", "TB1", "TM2", "TB1?").WithLocation(10, 9) + // (12,12): warning CS8631: The type 'TB1' cannot be used as type parameter 'TA' in the generic type or method 'IA'. Nullability of type argument 'TB1' doesn't match constraint type 'object'. + // IA x1; // 1 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "TB1").WithArguments("IA", "object", "TA", "TB1").WithLocation(12, 12), + // (12,12): warning CS8631: The type 'TB1' cannot be used as type parameter 'TA' in the generic type or method 'IA'. Nullability of type argument 'TB1' doesn't match constraint type 'IB'. + // IA x1; // 1 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "TB1").WithArguments("IA", "IB", "TA", "TB1").WithLocation(12, 12), + // (12,12): warning CS8631: The type 'TB1' cannot be used as type parameter 'TA' in the generic type or method 'IA'. Nullability of type argument 'TB1' doesn't match constraint type 'IC'. + // IA x1; // 1 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "TB1").WithArguments("IA", "IC", "TA", "TB1").WithLocation(12, 12), + // (20,9): warning CS8631: The type 'TB1' cannot be used as type parameter 'TM1' in the generic type or method 'B.M1(TM1)'. Nullability of type argument 'TB1' doesn't match constraint type 'object'. + // M1(a2); // 2 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "M1").WithArguments("B.M1(TM1)", "object", "TM1", "TB1").WithLocation(20, 9), + // (20,9): warning CS8631: The type 'TB1' cannot be used as type parameter 'TM1' in the generic type or method 'B.M1(TM1)'. Nullability of type argument 'TB1' doesn't match constraint type 'IB'. + // M1(a2); // 2 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "M1").WithArguments("B.M1(TM1)", "IB", "TM1", "TB1").WithLocation(20, 9), + // (20,9): warning CS8631: The type 'TB1' cannot be used as type parameter 'TM1' in the generic type or method 'B.M1(TM1)'. Nullability of type argument 'TB1' doesn't match constraint type 'IC'. + // M1(a2); // 2 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "M1").WithArguments("B.M1(TM1)", "IC", "TM1", "TB1").WithLocation(20, 9), + // (21,9): warning CS8631: The type 'TB1' cannot be used as type parameter 'TM1' in the generic type or method 'B.M1(TM1)'. Nullability of type argument 'TB1' doesn't match constraint type 'object'. + // M1(a2); // 3 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "M1").WithArguments("B.M1(TM1)", "object", "TM1", "TB1").WithLocation(21, 9), + // (21,9): warning CS8631: The type 'TB1' cannot be used as type parameter 'TM1' in the generic type or method 'B.M1(TM1)'. Nullability of type argument 'TB1' doesn't match constraint type 'IB'. + // M1(a2); // 3 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "M1").WithArguments("B.M1(TM1)", "IB", "TM1", "TB1").WithLocation(21, 9), + // (21,9): warning CS8631: The type 'TB1' cannot be used as type parameter 'TM1' in the generic type or method 'B.M1(TM1)'. Nullability of type argument 'TB1' doesn't match constraint type 'IC'. + // M1(a2); // 3 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "M1").WithArguments("B.M1(TM1)", "IC", "TM1", "TB1").WithLocation(21, 9) ); } @@ -43478,21 +45028,22 @@ static void F5(E o) { } }"; var comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); comp.VerifyDiagnostics( - // (2,11): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // (2,22): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // interface IB : IA { } - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "IB").WithLocation(2, 11), - // (5,7): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(2, 22), + // (5,20): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // class B : A<(T, T?)> { } - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "B").WithLocation(5, 7), - // (6,7): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(5, 20), + // (6,22): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // class C : A, IA, IC { } - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "C").WithLocation(6, 7), - // (7,7): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(6, 22), + // (7,29): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // class D : A, IA, IC { } - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "D").WithLocation(7, 7), - // (8,7): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "U?").WithLocation(7, 29), + // (8,36): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // class E : A, IA, IC { } - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "E").WithLocation(8, 7)); + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "V?").WithLocation(8, 36) + ); } [Fact] @@ -43510,9 +45061,9 @@ static void F() where U : A { } // (1,29): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // interface I where U : T? { } Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(1, 29), - // (5,37): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // (5,39): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // static void F() where U : A { } - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "A").WithLocation(5, 37) + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(5, 39) ); } @@ -43544,27 +45095,31 @@ static void M(T? t, U? u) { } // (5,10): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // delegate T? D(); Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(5, 10), - // (12,8): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // (11,30): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // const object c = default(T?[]); + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(11, 30), + // (12,5): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // T? F; - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "F").WithLocation(12, 8), + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(12, 5), // (13,7): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // B(T? t) { } - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T? t").WithLocation(13, 7), + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(13, 7), // (14,22): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // static void M(T? t, U? u) { } - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T? t").WithLocation(14, 22), + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(14, 22), // (14,28): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // static void M(T? t, U? u) { } - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "U? u").WithLocation(14, 28), - // (15,12): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "U?").WithLocation(14, 28), + // (15,14): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // static B P { get; set; } - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "B").WithLocation(15, 12), - // (16,28): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(15, 14), + // (16,24): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // event EventHandler E; - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "E").WithLocation(16, 28), - // (17,37): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(16, 24), + // (17,39): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public static explicit operator A(B t) => throw null; - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "A").WithLocation(17, 37)); + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(17, 39) + ); } [Fact] @@ -43597,16 +45152,16 @@ class C comp.VerifyDiagnostics( // (16,12): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // static U?[] F2() where T : class where U : T => throw null; - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "U?[]").WithLocation(16, 12), + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "U?").WithLocation(16, 12), // (18,12): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // static U?[] F4() where T : new() where U : T => throw null; // error - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "U?[]").WithLocation(18, 12), + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "U?").WithLocation(18, 12), // (20,12): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // static U?[] F6() where T : I where U : T => throw null; // error - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "U?[]").WithLocation(20, 12), + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "U?").WithLocation(20, 12), // (15,12): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // static U?[] F1() where U : T => throw null; // error - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "U?[]").WithLocation(15, 12), + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "U?").WithLocation(15, 12), // (17,23): error CS0456: Type parameter 'T' has the 'struct' constraint so 'T' cannot be used as a constraint for 'U' // static U?[] F3() where T : struct where U : T => throw null; Diagnostic(ErrorCode.ERR_ConWithValCon, "U").WithArguments("U", "T").WithLocation(17, 23), @@ -43653,22 +45208,22 @@ internal override void F7(U? u) { } comp.VerifyDiagnostics( // (4,34): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // internal abstract void F1(T? t); // error - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T? t").WithLocation(4, 34), + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(4, 34), // (7,34): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // internal abstract void F4(T? t) where T : new(); // error - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T? t").WithLocation(7, 34), + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(7, 34), // (9,34): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // internal abstract void F6(T? t) where T : I; // error - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T? t").WithLocation(9, 34), + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(9, 34), // (14,34): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // internal override void F1(U? u) { } // error - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "U? u").WithLocation(14, 34), + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "U?").WithLocation(14, 34), // (17,34): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // internal override void F4(U? u) { } // error - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "U? u").WithLocation(17, 34), + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "U?").WithLocation(17, 34), // (19,34): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // internal override void F6(U? u) { } // error - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "U? u").WithLocation(19, 34)); + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "U?").WithLocation(19, 34)); } [Fact] @@ -43687,12 +45242,13 @@ static void F2(A.E[] e) { } }"; var comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); comp.VerifyDiagnostics( - // (9,23): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // (9,25): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // static void F2(A.E[] e) { } - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "A.E[] e").WithLocation(9, 23), - // (8,23): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(9, 25), + // (8,25): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // static void F1(A.I i) { } - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "A.I i").WithLocation(8, 23)); + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(8, 25) + ); } [Fact] @@ -43711,8 +45267,20 @@ static void M() } }"; var comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition }); - // PROTOTYPE(NullableReferenceTypes): Report errors within method body. - comp.VerifyDiagnostics(); + comp.VerifyDiagnostics( + // (6,9): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // T? t; + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(6, 9), + // (7,24): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // var u = typeof(U?); + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "U?").WithLocation(7, 24), + // (8,29): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // object? o = default(T?); + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(8, 29), + // (9,17): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // o = new U?[0]; + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "U?").WithLocation(9, 17) + ); } [Fact] @@ -43732,7 +45300,7 @@ static void G() comp.VerifyDiagnostics( // (7,12): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // F((T? t) => { }); - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T? t").WithLocation(7, 12)); + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(7, 12)); } [Fact] @@ -43758,7 +45326,7 @@ void L2(T?[] t) { } Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(6, 9), // (10,20): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // void L2(T?[] t) { } - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?[] t").WithLocation(10, 20)); + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(10, 20)); } [Fact] @@ -44234,9 +45802,9 @@ static void Main() // (3,15): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // where U : T? Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(3, 15), - // (3,15): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (3,16): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // where U : T? - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "T?").WithLocation(3, 15) + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(3, 16) ); MetadataReference ref0 = comp.ToMetadataReference(); @@ -44385,15 +45953,19 @@ class C4 : I, I { }"; // (5,7): error CS0695: 'C4' cannot implement both 'I' and 'I' because they may unify for some type parameter substitutions // class C4 : I, I { } Diagnostic(ErrorCode.ERR_UnifyingInterfaceInstantiations, "C4").WithArguments("C4", "I", "I").WithLocation(5, 7), - // (4,7): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // (4,20): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // class C3 : I, I { } - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "C3").WithLocation(4, 7), - // (5,7): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(4, 20), + // (5,20): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // class C4 : I, I { } + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(5, 20), + // (5,27): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // class C4 : I, I { } - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "C4").WithLocation(5, 7), - // (3,7): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "U?").WithLocation(5, 27), + // (3,26): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // class C2 : I, I { } - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "C2").WithLocation(3, 7)); + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "U?").WithLocation(3, 26) + ); } [Fact] @@ -44413,18 +45985,19 @@ class C4 : I, I where T : struct { }"; // (3,7): error CS0695: 'C2' cannot implement both 'I' and 'I' because they may unify for some type parameter substitutions // class C2 : I, I where T : struct { } Diagnostic(ErrorCode.ERR_UnifyingInterfaceInstantiations, "C2").WithArguments("C2", "I", "I").WithLocation(3, 7), - // (3,7): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. - // class C2 : I, I where T : struct { } - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "C2").WithLocation(3, 7), + // (3,26): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // class C2 : I, I where T : class { } + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "U?").WithLocation(3, 26), // (4,7): error CS0695: 'C3' cannot implement both 'I' and 'I' because they may unify for some type parameter substitutions // class C3 : I, I where T : struct { } Diagnostic(ErrorCode.ERR_UnifyingInterfaceInstantiations, "C3").WithArguments("C3", "I", "I").WithLocation(4, 7), // (5,7): error CS0695: 'C4' cannot implement both 'I' and 'I' because they may unify for some type parameter substitutions // class C4 : I, I where T : struct { } Diagnostic(ErrorCode.ERR_UnifyingInterfaceInstantiations, "C4").WithArguments("C4", "I", "I").WithLocation(5, 7), - // (5,7): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. - // class C4 : I, I where T : struct { } - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "C4").WithLocation(5, 7)); + // (5,27): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // class C4 : I, I where T : class { } + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "U?").WithLocation(5, 27) + ); } [Fact] @@ -44444,18 +46017,19 @@ class C4 : I, I where T : class { }"; // (3,7): error CS0695: 'C2' cannot implement both 'I' and 'I' because they may unify for some type parameter substitutions // class C2 : I, I where T : class { } Diagnostic(ErrorCode.ERR_UnifyingInterfaceInstantiations, "C2").WithArguments("C2", "I", "I").WithLocation(3, 7), - // (3,7): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // (3,26): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // class C2 : I, I where T : class { } - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "C2").WithLocation(3, 7), + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "U?").WithLocation(3, 26), // (4,7): error CS0695: 'C3' cannot implement both 'I' and 'I' because they may unify for some type parameter substitutions // class C3 : I, I where T : class { } Diagnostic(ErrorCode.ERR_UnifyingInterfaceInstantiations, "C3").WithArguments("C3", "I", "I").WithLocation(4, 7), // (5,7): error CS0695: 'C4' cannot implement both 'I' and 'I' because they may unify for some type parameter substitutions // class C4 : I, I where T : class { } Diagnostic(ErrorCode.ERR_UnifyingInterfaceInstantiations, "C4").WithArguments("C4", "I", "I").WithLocation(5, 7), - // (5,7): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // (5,27): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // class C4 : I, I where T : class { } - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "C4").WithLocation(5, 7)); + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "U?").WithLocation(5, 27) + ); } [Fact] @@ -44770,12 +46344,12 @@ public class A2 { } [NonNullTypes(false)] public class B2 where T : A2 where U : A2 { }"; var comp0 = CreateCompilation(new[] { source0, NonNullTypesAttributesDefinition }); comp0.VerifyDiagnostics( - // (4,68): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (4,70): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // [NonNullTypes(false)] public class B1 where T : A1 where U : A1? { } - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "A1?").WithLocation(4, 68), - // (5,76): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(4, 70), + // (5,85): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // [NonNullTypes(false)] public class B2 where T : A2 where U : A2 { } - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "A2").WithLocation(5, 76) + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(5, 85) ); var ref0 = comp0.EmitToImageReference(); @@ -44818,24 +46392,24 @@ public abstract class A where T : class }"; var comp0 = CreateCompilation(new[] { source0, NonNullTypesAttributesDefinition }); comp0.VerifyDiagnostics( - // (6,66): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (6,67): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // [NonNullTypes(false)] public abstract void F2() where U : T?, I; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "T?").WithLocation(6, 66), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(6, 67), // (6,66): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // [NonNullTypes(false)] public abstract void F2() where U : T?, I; Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(6, 66), - // (6,70): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (6,73): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // [NonNullTypes(false)] public abstract void F2() where U : T?, I; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "I").WithLocation(6, 70), - // (6,70): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(6, 73), + // (6,72): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // [NonNullTypes(false)] public abstract void F2() where U : T?, I; - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "I").WithLocation(6, 70), + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(6, 72), // (8,65): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // [NonNullTypes(true)] public abstract void F4() where U : T?, I; Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(8, 65), - // (8,69): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // (8,71): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // [NonNullTypes(true)] public abstract void F4() where U : T?, I; - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "I").WithLocation(8, 69) + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(8, 71) ); var source = @@ -44874,33 +46448,36 @@ public override void F4() { } }"; var comp = CreateCompilation(new[] { source, NonNullTypesTrue }, references: new[] { new CSharpCompilationReference(comp0) }); comp.VerifyDiagnostics( - // (11,7): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (11,20): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // class B2 : A - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "B2").WithLocation(11, 7)); + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(11, 20) + ); verifyAllConstraintTypes(); comp0 = CreateCompilation(new[] { source0, NonNullTypesAttributesDefinition, NonNullTypesTrue }); comp0.VerifyDiagnostics( - // (6,66): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (6,67): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // [NonNullTypes(false)] public abstract void F2() where U : T?, I; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "T?").WithLocation(6, 66), - // (6,70): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(6, 67), + // (6,73): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // [NonNullTypes(false)] public abstract void F2() where U : T?, I; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "I").WithLocation(6, 70) + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(6, 73) ); comp = CreateCompilation(new[] { source, NonNullTypesTrue }, references: new[] { new CSharpCompilationReference(comp0) }); comp.VerifyDiagnostics( - // (11,7): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (11,20): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // class B2 : A - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "B2").WithLocation(11, 7)); + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(11, 20) + ); verifyAllConstraintTypes(); comp = CreateCompilation(new[] { source, NonNullTypesTrue }, references: new[] { comp0.EmitToImageReference() }); comp.VerifyDiagnostics( - // (11,7): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (11,20): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // class B2 : A - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "B2").WithLocation(11, 7)); + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(11, 20) + ); verifyAllConstraintTypes(); void verifyAllConstraintTypes() @@ -44968,24 +46545,43 @@ void local(T t, T2 t2, T3 t3, string? s) where T : C where T2 : C? wh }"; var comp = CreateCompilation(new[] { source, NonNullTypesAttributesDefinition }); - // PROTOTYPE(NullableReferenceTypes): Missing WRN_MissingNonNullTypesContextForAnnotation for '?' in constraints - // (18,98): - // void local(T t, T2 t2, T3 t3, string? s) where T : C where T2 : C? where T3 : T? - // (27,98): - // void local(T t, T2 t2, T3 t3, string? s) where T : C where T2 : C? where T3 : T? comp.VerifyDiagnostics( + // (18,56): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // void local(T t, T2 t2, T3 t3, string? s) where T : C where T2 : C? where T3 : T? + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(18, 56), + // (18,85): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // void local(T t, T2 t2, T3 t3, string? s) where T : C where T2 : C? where T3 : T? + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(18, 85), + // (18,99): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // void local(T t, T2 t2, T3 t3, string? s) where T : C where T2 : C? where T3 : T? + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(18, 99), // (18,98): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // void local(T t, T2 t2, T3 t3, string? s) where T : C where T2 : C? where T3 : T? Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(18, 98), + // (20,13): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // T? x = t; // warn 1 + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(20, 13), // (20,14): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // T? x = t; // warn 1 Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(20, 14), + // (27,56): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // void local(T t, T2 t2, T3 t3, string? s) where T : C where T2 : C? where T3 : T? + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(27, 56), + // (27,85): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // void local(T t, T2 t2, T3 t3, string? s) where T : C where T2 : C? where T3 : T? + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(27, 85), + // (27,99): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // void local(T t, T2 t2, T3 t3, string? s) where T : C where T2 : C? where T3 : T? + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(27, 99), // (27,98): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // void local(T t, T2 t2, T3 t3, string? s) where T : C where T2 : C? where T3 : T? Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(27, 98), // (29,14): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // T? x = t; // warn 2 Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(29, 14), + // (29,13): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // T? x = t; // warn 2 + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(29, 13), // (30,14): warning CS8629: The suppression operator (!) should be used in code with a '[NonNullTypes(true/false)]' context. // x!.ToString(); // warn 3 Diagnostic(ErrorCode.WRN_MissingNonNullTypesContext, "!").WithLocation(30, 14) @@ -45119,27 +46715,27 @@ class D }"; var comp = CreateCompilation(new[] { source, NonNullTypesAttributesDefinition }, references: new[] { ref0 }); comp.VerifyDiagnostics( - // (4,23): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (4,24): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // class B1 where T : A? { } - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "A?").WithLocation(4, 23), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(4, 24), // (18,8): warning CS8631: The type 'A?' cannot be used as type parameter 'T' in the generic type or method 'B4'. Nullability of type argument 'A?' doesn't match constraint type 'A'. // B4 F9; // 5 and 6 Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "A?").WithArguments("B4", "A", "T", "A?").WithLocation(18, 8), - // (12,12): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (12,9): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // B1 F3; // 2 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "F3").WithLocation(12, 12), - // (14,12): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(12, 9), + // (14,9): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // B2 F5; // 3 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "F5").WithLocation(14, 12), - // (16,12): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(14, 9), + // (16,9): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // B3 F7; // 4 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "F7").WithLocation(16, 12), - // (18,12): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(16, 9), + // (18,9): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // B4 F9; // 5 and 6 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "F9").WithLocation(18, 12), - // (10,12): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(18, 9), + // (10,9): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // B0 F1; // 1 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "F1").WithLocation(10, 12), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(10, 9), // (32,8): warning CS8631: The type 'A?' cannot be used as type parameter 'T' in the generic type or method 'B4'. Nullability of type argument 'A?' doesn't match constraint type 'A'. // B4 G9; // 7 Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "A?").WithArguments("B4", "A", "T", "A?").WithLocation(32, 8) @@ -45193,24 +46789,24 @@ class D }"; var comp = CreateCompilation(new[] { source, NonNullTypesAttributesDefinition }, references: new[] { ref0 }); comp.VerifyDiagnostics( - // (4,23): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (4,31): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // class B1 where T : A { } - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "A").WithLocation(4, 23), - // (12,20): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(4, 31), + // (12,16): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // B1> F3; // 2 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "F3").WithLocation(12, 20), - // (14,20): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(12, 16), + // (14,16): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // B2> F5; // 3 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "F5").WithLocation(14, 20), - // (16,20): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(14, 16), + // (16,16): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // B3> F7; // 4 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "F7").WithLocation(16, 20), - // (18,20): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(16, 16), + // (18,16): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // B4> F9; // 5 and 6 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "F9").WithLocation(18, 20), - // (10,20): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(18, 16), + // (10,16): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // B0> F1; // 1 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "F1").WithLocation(10, 20), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(10, 16), // (27,8): warning CS8631: The type 'A' cannot be used as type parameter 'T' in the generic type or method 'B1'. Nullability of type argument 'A' doesn't match constraint type 'A'. // B1> G4; // 7 Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "A").WithArguments("B1", "A", "T", "A").WithLocation(27, 8), @@ -45253,18 +46849,18 @@ class B2 where T : A2 { } // 2 var comp = CreateCompilation(new[] { source }, references: new[] { ref0 }); comp.VerifyDiagnostics( - // (2,23): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (2,30): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // class B1 where T : A1 { } // 1 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "A1").WithLocation(2, 23), - // (2,23): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(2, 30), + // (2,29): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // class B1 where T : A1 { } // 1 - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "A1").WithLocation(2, 23), - // (3,23): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(2, 29), + // (3,27): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // class B2 where T : A2 { } // 2 - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "A2").WithLocation(3, 23), - // (3,23): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(3, 27), + // (3,26): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // class B2 where T : A2 { } // 2 - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "A2").WithLocation(3, 23) + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(3, 26) ); } @@ -45667,12 +47263,12 @@ static void Main() // No [NullNullTypes] var comp0 = CreateCompilation(source0); comp0.VerifyDiagnostics( - // (2,37): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // (2,48): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public class A2 where T : class, IEquatable { } - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "IEquatable").WithLocation(2, 37), - // (2,37): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(2, 48), + // (2,49): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public class A2 where T : class, IEquatable { } - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "IEquatable").WithLocation(2, 37) + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(2, 49) ); MetadataReference ref0 = comp0.ToMetadataReference(); @@ -45688,12 +47284,12 @@ static void Main() // [NullNullTypes(false)] comp0 = CreateCompilation(new[] { source0, NonNullTypesFalse, NonNullTypesAttributesDefinition }); comp0.VerifyDiagnostics( - // (2,37): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + // (2,48): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public class A2 where T : class, IEquatable { } - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "IEquatable").WithLocation(2, 37), - // (2,37): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(2, 48), + // (2,49): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public class A2 where T : class, IEquatable { } - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "IEquatable").WithLocation(2, 37) + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(2, 49) ); ref0 = comp0.ToMetadataReference(); comp = CreateCompilation(source, references: new[] { ref0 }); diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/UninitializedNonNullableFieldTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/UninitializedNonNullableFieldTests.cs index 909bc963703c5..ec046d87dab6c 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/UninitializedNonNullableFieldTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/UninitializedNonNullableFieldTests.cs @@ -525,12 +525,12 @@ class C where T : struct // (10,8): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // T? F3; comp.VerifyDiagnostics( - // (10,8): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (10,6): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // T? F3; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "F3").WithLocation(10, 8), - // (10,8): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(10, 6), + // (10,5): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // T? F3; - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "F3").WithLocation(10, 8), + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(10, 5), // (5,5): warning CS8618: Non-nullable field 'F1' is uninitialized. // A() { } Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "A").WithArguments("field", "F1").WithLocation(5, 5), @@ -545,12 +545,12 @@ class C where T : struct // [NonNullTypes] missing comp = CreateCompilation(source, parseOptions: TestOptions.Regular8); comp.VerifyDiagnostics( - // (10,8): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (10,6): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // T? F3; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "F3").WithLocation(10, 8), - // (10,8): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(10, 6), + // (10,5): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // T? F3; - Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "F3").WithLocation(10, 8) + Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(10, 5) ); // PROTOTYPE(NullableReferenceTypes): Test with [NonNullTypes(Warnings=false)]. diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/GenericConstraintTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/GenericConstraintTests.cs index 5575eedcc82df..a84d18e212fd1 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/GenericConstraintTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/GenericConstraintTests.cs @@ -108,7 +108,7 @@ void I.M() { } { var type = module.GlobalNamespace.GetMember("C"); var method = type.GetMethod("I.M"); - CheckConstraints(method.TypeParameters[0], TypeParameterConstraintKind.None, false, true, "C", "C", "C"); + CheckConstraints(method.TypeParameters[0], TypeParameterConstraintKind.None, false, true, "C", "C", "C", "object"); }; CompileAndVerify( @@ -5169,11 +5169,10 @@ static void Main() } /// - /// Redundant System.Object constraints should be removed - /// and '.ctor' and System.ValueType constraints should be + /// Redundant '.ctor' and System.ValueType constraints should be /// removed if 'valuetype' is specified. By contrast, redundant /// 'class' constraints should not be removed if explicit class - /// constraint is specified. + /// constraint is specified. System.Object constraint shouldn't be removed either. /// [WorkItem(543335, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543335")] [ClrOnlyFact(ClrOnlyReason.Ilasm)] @@ -5194,7 +5193,7 @@ .class public V2 { } var compilation = CreateCompilationWithILAndMscorlib40(csharpSource, ilSource); var @namespace = compilation.GlobalNamespace; CheckConstraints(@namespace.GetMember("O1").TypeParameters[0], TypeParameterConstraintKind.None, false, false, "object", "object"); - CheckConstraints(@namespace.GetMember("O2").TypeParameters[0], TypeParameterConstraintKind.None, false, false, "object", "object"); + CheckConstraints(@namespace.GetMember("O2").TypeParameters[0], TypeParameterConstraintKind.None, false, false, "object", "object", "object"); CheckConstraints(@namespace.GetMember("V1").TypeParameters[0], TypeParameterConstraintKind.ValueType, true, false, "ValueType", "ValueType"); CheckConstraints(@namespace.GetMember("V2").TypeParameters[0], TypeParameterConstraintKind.ValueType, true, false, "ValueType", "ValueType"); CheckConstraints(@namespace.GetMember("V3").TypeParameters[0], TypeParameterConstraintKind.ValueType, true, false, "ValueType", "ValueType"); @@ -5240,8 +5239,8 @@ .method public specialname rtspecialname instance void .ctor() { ret } CheckConstraints(type.GetMember("M1").TypeParameters[0], TypeParameterConstraintKind.None, false, false, "object", "object"); CheckConstraints(type.GetMember("M2").TypeParameters[0], TypeParameterConstraintKind.ValueType, true, false, "ValueType", "ValueType"); type = @namespace.GetMember("B1"); - CheckConstraints(type.GetMember("M1").TypeParameters[0], TypeParameterConstraintKind.None, false, false, "object", "object"); - CheckConstraints(type.GetMember("M2").TypeParameters[0], TypeParameterConstraintKind.ValueType, true, false, "ValueType", "ValueType"); + CheckConstraints(type.GetMember("M1").TypeParameters[0], TypeParameterConstraintKind.None, false, false, "object", "object", "object"); + CheckConstraints(type.GetMember("M2").TypeParameters[0], TypeParameterConstraintKind.ValueType, true, false, "ValueType", "ValueType", "object"); type = @namespace.GetMember("B2"); CheckConstraints(type.GetMember("M1").TypeParameters[0], TypeParameterConstraintKind.None, false, false, "ValueType", "ValueType", "ValueType"); CheckConstraints(type.GetMember("M2").TypeParameters[0], TypeParameterConstraintKind.ValueType, true, false, "ValueType", "ValueType"); @@ -5349,10 +5348,6 @@ public override void M2() { } CreateCompilationWithILAndMscorlib40(csharpSource, ilSource).VerifyDiagnostics(); } - /// - /// Object constraints should be dropped from TypeParameterSymbol.ConstraintTypes - /// on import and type substitution. - /// [WorkItem(543831, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543831")] [ClrOnlyFact(ClrOnlyReason.Ilasm)] public void ObjectConstraintTypes() @@ -5418,13 +5413,13 @@ class D0 : D var compilation = CreateCompilationWithILAndMscorlib40(csharpSource, ilSource).VerifyDiagnostics(); var @namespace = compilation.GlobalNamespace; var type = @namespace.GetMember("I0"); - CheckConstraints(type.Interfaces()[0].GetMember("M").TypeParameters[0], TypeParameterConstraintKind.None, false, false, "object", "object"); + CheckConstraints(type.Interfaces()[0].GetMember("M").TypeParameters[0], TypeParameterConstraintKind.None, false, false, "object", "object", "object"); type = @namespace.GetMember("A1"); CheckConstraints(type.GetMember("M").TypeParameters[0], TypeParameterConstraintKind.None, false, false, "object", "object"); type = @namespace.GetMember("A2"); - CheckConstraints(type.GetMember("M").TypeParameters[0], TypeParameterConstraintKind.None, false, false, "object", "object"); + CheckConstraints(type.GetMember("M").TypeParameters[0], TypeParameterConstraintKind.None, false, false, "object", "object", "object"); type = @namespace.GetMember("I1"); - CheckConstraints(type.Interfaces()[0].GetMember("M").TypeParameters[0], TypeParameterConstraintKind.None, false, false, "object", "object"); + CheckConstraints(type.Interfaces()[0].GetMember("M").TypeParameters[0], TypeParameterConstraintKind.None, false, false, "object", "object", "object"); type = @namespace.GetMember("B0"); CheckConstraints(type.GetMember("M").TypeParameters[0], TypeParameterConstraintKind.None, false, false, "object", "object"); type = @namespace.GetMember("B1"); @@ -5436,9 +5431,9 @@ class D0 : D type = @namespace.GetMember("C1"); CheckConstraints(type.GetMember("M").TypeParameters[0], TypeParameterConstraintKind.None, false, false, "object", "object"); type = @namespace.GetMember("C2"); - CheckConstraints(type.GetMethod("I.M").TypeParameters[0], TypeParameterConstraintKind.None, false, false, "object", "object"); + CheckConstraints(type.GetMethod("I.M").TypeParameters[0], TypeParameterConstraintKind.None, false, false, "object", "object", "object"); type = @namespace.GetMember("D0"); - CheckConstraints(type.BaseType().GetMember("M").TypeParameters[0], TypeParameterConstraintKind.None, false, false, "object", "object"); + CheckConstraints(type.BaseType().GetMember("M").TypeParameters[0], TypeParameterConstraintKind.None, false, false, "object", "object", "object"); } /// @@ -5473,7 +5468,7 @@ public override void M() { } type = module.GlobalNamespace.GetMember("I1"); CheckConstraints(type.TypeParameters[0], TypeParameterConstraintKind.None, false, true, "C", "C", "C"); var method = module.GlobalNamespace.GetMember("A0").GetMember("M"); - CheckConstraints(method.TypeParameters[0], TypeParameterConstraintKind.None, false, false, "object", "object"); + CheckConstraints(method.TypeParameters[0], TypeParameterConstraintKind.None, false, false, "object", "object", "object"); method = module.GlobalNamespace.GetMember("A1").GetMember("M"); CheckConstraints(method.TypeParameters[0], TypeParameterConstraintKind.None, false, true, "C", "C", "C"); }; @@ -5537,16 +5532,16 @@ public override void M4() { } var compilation = CreateCompilation(source); var @namespace = compilation.GlobalNamespace; var type = @namespace.GetMember("C0"); - CheckConstraints(type.GetMember("M1").TypeParameters[0], TypeParameterConstraintKind.None, false, false, "object", "object"); - CheckConstraints(type.GetMember("M2").TypeParameters[0], TypeParameterConstraintKind.ValueType, true, false, "ValueType", "ValueType"); + CheckConstraints(type.GetMember("M1").TypeParameters[0], TypeParameterConstraintKind.None, false, false, "object", "object", "object"); + CheckConstraints(type.GetMember("M2").TypeParameters[0], TypeParameterConstraintKind.ValueType, true, false, "ValueType", "ValueType", "object"); type = @namespace.GetMember("C1"); CheckConstraints(type.GetMember("M1").TypeParameters[0], TypeParameterConstraintKind.None, false, false, "ValueType", "ValueType", "ValueType"); CheckConstraints(type.GetMember("M2").TypeParameters[0], TypeParameterConstraintKind.ValueType, true, false, "ValueType", "ValueType", "ValueType"); type = @namespace.GetMember("D0"); - CheckConstraints(type.GetMember("M1").TypeParameters[0], TypeParameterConstraintKind.None, false, false, "object", "object", "IA"); - CheckConstraints(type.GetMember("M2").TypeParameters[0], TypeParameterConstraintKind.None, false, false, "object", "object", "IB"); - CheckConstraints(type.GetMember("M3").TypeParameters[0], TypeParameterConstraintKind.None, false, true, "A", "A", "A"); - CheckConstraints(type.GetMember("M4").TypeParameters[0], TypeParameterConstraintKind.None, false, true, "B", "B", "B"); + CheckConstraints(type.GetMember("M1").TypeParameters[0], TypeParameterConstraintKind.None, false, false, "object", "object", "IA", "object"); + CheckConstraints(type.GetMember("M2").TypeParameters[0], TypeParameterConstraintKind.None, false, false, "object", "object", "IB", "object"); + CheckConstraints(type.GetMember("M3").TypeParameters[0], TypeParameterConstraintKind.None, false, true, "A", "A", "A", "object"); + CheckConstraints(type.GetMember("M4").TypeParameters[0], TypeParameterConstraintKind.None, false, true, "B", "B", "B", "object"); type = @namespace.GetMember("D1"); CheckConstraints(type.GetMember("M1").TypeParameters[0], TypeParameterConstraintKind.None, false, false, "object", "object", "IA"); CheckConstraints(type.GetMember("M2").TypeParameters[0], TypeParameterConstraintKind.None, false, false, "object", "object", "IB", "IA"); @@ -5605,18 +5600,18 @@ class B : A } "; CreateCompilation(source, options: TestOptions.ReleaseDll).VerifyDiagnostics( - // (4,20): error CS8627: A nullable type parameter must be known to be a value or reference type. Consider adding a 'class', 'struct', or type constraint. + // (4,20): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public virtual T? Goo() Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(4, 20), - // (4,20): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (4,21): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public virtual T? Goo() - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "T?").WithLocation(4, 20), - // (12,21): error CS8627: A nullable type parameter must be known to be a value or reference type. Consider adding a 'class', 'struct', or type constraint. + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(4, 21), + // (12,21): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint. // public override T? Goo() Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(12, 21), - // (12,21): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (12,22): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // public override T? Goo() - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "T?").WithLocation(12, 21), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(12, 22), // (6,16): error CS0403: Cannot convert null to type parameter 'T' because it could be a non-nullable value type. Consider using 'default(T)' instead. // return null; Diagnostic(ErrorCode.ERR_TypeVarCantBeNull, "null").WithArguments("T").WithLocation(6, 16), @@ -6341,9 +6336,9 @@ public void DoSomething(T t) { } public class E { } "; CreateCompilation(source).VerifyDiagnostics( - // (4,10): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. + // (4,6): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context. // E?[] eNullableArr; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "eNullableArr").WithLocation(4, 10), + Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(4, 6), // (4,10): warning CS0649: Field 'S.eNullableArr' is never assigned to, and will always have its default value null // E?[] eNullableArr; Diagnostic(ErrorCode.WRN_UnassignedInternalField, "eNullableArr").WithArguments("S.eNullableArr", "null").WithLocation(4, 10)); diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/SymbolErrorTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/SymbolErrorTests.cs index 6dca1f9eb2be5..839003380f73c 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/SymbolErrorTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/SymbolErrorTests.cs @@ -12317,10 +12317,6 @@ interface IB where T : System.Object { } interface IC where T : ValueType { } interface ID where T : Array { }"; CreateCompilation(source).VerifyDiagnostics( - // (2,27): error CS0702: Constraint cannot be special class 'object' - Diagnostic(ErrorCode.ERR_SpecialTypeAsBound, "object").WithArguments("object").WithLocation(2, 27), - // (3,27): error CS0702: Constraint cannot be special class 'object' - Diagnostic(ErrorCode.ERR_SpecialTypeAsBound, "System.Object").WithArguments("object").WithLocation(3, 27), // (4,30): error CS0702: Constraint cannot be special class 'System.ValueType' Diagnostic(ErrorCode.ERR_SpecialTypeAsBound, "ValueType").WithArguments("System.ValueType").WithLocation(4, 30), // (5,27): error CS0702: Constraint cannot be special class 'System.Array' diff --git a/src/Compilers/VisualBasic/Portable/Symbols/MethodSignatureComparer.vb b/src/Compilers/VisualBasic/Portable/Symbols/MethodSignatureComparer.vb index 482498037b7c7..1121dcc130609 100644 --- a/src/Compilers/VisualBasic/Portable/Symbols/MethodSignatureComparer.vb +++ b/src/Compilers/VisualBasic/Portable/Symbols/MethodSignatureComparer.vb @@ -904,6 +904,11 @@ Done: ''' Private Shared Function AreConstraintTypesSubset(constraintTypes1 As ArrayBuilder(Of TypeSymbol), constraintTypes2 As ArrayBuilder(Of TypeSymbol)) As Boolean For Each constraintType In constraintTypes1 + ' Skip object type. + If constraintType.IsObjectType() Then + Continue For + End If + If Not ContainsIgnoringCustomModifiers(constraintTypes2, constraintType) Then Return False End If diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/GenericConstraintTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/GenericConstraintTests.vb index c973e61567213..8d5299f03a13b 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/GenericConstraintTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/GenericConstraintTests.vb @@ -3889,12 +3889,6 @@ End Class Dim compilation = CreateCompilationWithCustomILSource(vbSource, ilSource) compilation.AssertTheseDiagnostics(