From 934f8daf4b24ca046a30585a1910dc47c390c600 Mon Sep 17 00:00:00 2001 From: AlekseyTs Date: Wed, 14 Nov 2018 21:38:08 -0800 Subject: [PATCH 1/5] Adjust the way nullable annotations are represented in metadata. Closes #30075. Closes #30065. Closes #29594. --- .../CSharp/Portable/Binder/Binder.cs | 2 +- .../CSharp/Portable/Binder/BinderFlags.cs | 5 + .../CSharp/Portable/Binder/Binder_Symbols.cs | 30 +- .../Portable/BoundTree/UnboundLambda.cs | 2 +- .../Portable/CSharpResources.Designer.cs | 20 +- .../CSharp/Portable/CSharpResources.resx | 6 - .../Emitter/Model/PEAssemblyBuilder.cs | 118 +- .../Portable/Emitter/Model/PEModuleBuilder.cs | 40 +- .../Emitter/Model/PENetModuleBuilder.cs | 11 +- .../CSharp/Portable/Errors/ErrorCode.cs | 2 +- .../CSharp/Portable/Errors/MessageID.cs | 9 +- .../Portable/FlowAnalysis/NullableWalker.cs | 64 +- .../Lowering/LocalRewriter/LocalRewriter.cs | 12 +- .../Portable/Symbols/ArrayTypeSymbol.cs | 6 +- .../Symbols/Compilation_WellKnownMembers.cs | 15 +- .../Portable/Symbols/DynamicTypeSymbol.cs | 4 +- .../Portable/Symbols/ExtraAnnotations.cs | 13 +- .../Metadata/PE/NullableTypeDecoder.cs | 26 +- .../Symbols/Metadata/PE/PEEventSymbol.cs | 11 +- .../Symbols/Metadata/PE/PEFieldSymbol.cs | 9 +- .../Symbols/Metadata/PE/PEMethodSymbol.cs | 10 +- .../Symbols/Metadata/PE/PEModuleSymbol.cs | 2 +- .../Symbols/Metadata/PE/PENamedTypeSymbol.cs | 7 +- .../Symbols/Metadata/PE/PEParameterSymbol.cs | 17 +- .../Symbols/Metadata/PE/PEPropertySymbol.cs | 9 +- .../Metadata/PE/PETypeParameterSymbol.cs | 21 +- .../CSharp/Portable/Symbols/MethodSymbol.cs | 2 +- .../Portable/Symbols/NamedTypeSymbol.cs | 6 +- .../Portable/Symbols/NamespaceSymbol.cs | 2 +- .../Portable/Symbols/PointerTypeSymbol.cs | 6 +- .../Symbols/Source/CustomModifierUtils.cs | 10 +- .../FieldSymbolWithAttributesAndModifiers.cs | 9 +- .../Symbols/Source/LocalFunctionSymbol.cs | 2 +- .../Symbols/Source/ParameterHelpers.cs | 2 +- .../Symbols/Source/SourceCustomEventSymbol.cs | 4 +- .../Source/SourceDelegateMethodSymbol.cs | 2 +- .../Symbols/Source/SourceEventSymbol.cs | 16 +- .../Source/SourceFieldLikeEventSymbol.cs | 2 +- .../Symbols/Source/SourceFieldSymbol.cs | 2 +- .../Source/SourceMemberContainerSymbol.cs | 4 +- .../Source/SourceMemberMethodSymbol.cs | 7 - .../Symbols/Source/SourceModuleSymbol.cs | 12 - .../Symbols/Source/SourceNamedTypeSymbol.cs | 14 +- .../Symbols/Source/SourceNamespaceSymbol.cs | 186 +- .../Source/SourceOrdinaryMethodSymbol.cs | 2 +- .../Symbols/Source/SourceParameterSymbol.cs | 2 +- .../Source/SourceParameterSymbolBase.cs | 2 +- .../Source/SourcePropertyAccessorSymbol.cs | 2 +- .../Symbols/Source/SourcePropertySymbol.cs | 13 +- .../Source/SourceTypeParameterSymbol.cs | 15 +- .../SourceUserDefinedOperatorSymbolBase.cs | 2 +- .../CSharp/Portable/Symbols/Symbol.cs | 10 - .../Synthesized/InjectedAttributeSymbol.cs | 42 - .../InjectedEmbeddedAttributeSymbol.cs | 64 - .../InjectedNonNullTypesAttributeSymbol.cs | 130 -- .../SynthesizedEmbeddedAttributeSymbol.cs | 23 +- .../Synthesized/SynthesizedFieldSymbolBase.cs | 2 +- .../SynthesizedInstanceConstructor.cs | 2 +- .../Synthesized/SynthesizedParameterSymbol.cs | 32 +- .../Symbols/Tuples/TupleTypeSymbol.cs | 6 +- .../Portable/Symbols/TypeParameterSymbol.cs | 4 +- .../CSharp/Portable/Symbols/TypeSymbol.cs | 8 +- .../Portable/Symbols/TypeSymbolExtensions.cs | 2 +- .../Symbols/TypeSymbolWithAnnotations.cs | 76 +- .../Portable/xlf/CSharpResources.cs.xlf | 10 - .../Portable/xlf/CSharpResources.de.xlf | 10 - .../Portable/xlf/CSharpResources.es.xlf | 10 - .../Portable/xlf/CSharpResources.fr.xlf | 10 - .../Portable/xlf/CSharpResources.it.xlf | 10 - .../Portable/xlf/CSharpResources.ja.xlf | 10 - .../Portable/xlf/CSharpResources.ko.xlf | 10 - .../Portable/xlf/CSharpResources.pl.xlf | 10 - .../Portable/xlf/CSharpResources.pt-BR.xlf | 10 - .../Portable/xlf/CSharpResources.ru.xlf | 10 - .../Portable/xlf/CSharpResources.tr.xlf | 10 - .../Portable/xlf/CSharpResources.zh-Hans.xlf | 10 - .../Portable/xlf/CSharpResources.zh-Hant.xlf | 10 - .../Attributes/AttributeTests_Embedded.cs | 84 +- .../Attributes/AttributeTests_NonNullTypes.cs | 445 ----- .../Attributes/AttributeTests_Nullable.cs | 116 +- .../Test/Semantic/FlowAnalysis/StructTests.cs | 2 + .../Semantics/NullableReferenceTypesTests.cs | 1497 ++--------------- .../Symbol/Symbols/MissingSpecialMember.cs | 3 +- .../Test/Symbol/Symbols/Retargeting/NoPia.cs | 12 +- .../Portable/Emit/CommonPEModuleBuilder.cs | 16 +- .../EditAndContinue/DeltaMetadataWriter.cs | 3 - .../Core/Portable/MetadataReader/PEModule.cs | 64 +- .../Portable/PEWriter/FullMetadataWriter.cs | 3 - .../Portable/PEWriter/ReferenceIndexerBase.cs | 5 +- .../Portable/PEWriter/TypeReferenceIndexer.cs | 6 +- .../Attributes/AttributeDescription.cs | 6 +- .../Core/Portable/WellKnownMember.cs | 5 +- .../Core/Portable/WellKnownMembers.cs | 26 +- src/Compilers/Core/Portable/WellKnownTypes.cs | 6 - .../Test/Utilities/CSharp/CSharpTestBase.cs | 4 +- .../Portable/Emit/PEAssemblyBuilder.vb | 10 - .../Portable/Emit/PENetModuleBuilder.vb | 10 - .../WellKnownTypeValidationTests.vb | 20 +- .../GenerateType/GenerateTypeTests.cs | 4 +- .../GenerateConstructorTests.cs | 4 +- ...ateEqualsAndGetHashCodeFromMembersTests.cs | 4 +- .../Binders/EEMethodBinder.cs | 2 +- .../ExpressionCompiler/PseudoVariableTests.cs | 2 +- .../ReferencedModulesTests.cs | 15 +- .../ExpressionCompiler/UsingDebugInfoTests.cs | 8 +- .../ReferencedModulesTests.vb | 10 - .../CSharpTest/InteractiveSessionTests.cs | 4 +- .../Portable/Metadata/MetadataReaderUtils.cs | 4 +- src/Workspaces/CoreTest/SymbolKeyTests.cs | 9 +- 109 files changed, 666 insertions(+), 3071 deletions(-) delete mode 100644 src/Compilers/CSharp/Portable/Symbols/Synthesized/InjectedAttributeSymbol.cs delete mode 100644 src/Compilers/CSharp/Portable/Symbols/Synthesized/InjectedEmbeddedAttributeSymbol.cs delete mode 100644 src/Compilers/CSharp/Portable/Symbols/Synthesized/InjectedNonNullTypesAttributeSymbol.cs delete mode 100644 src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_NonNullTypes.cs diff --git a/src/Compilers/CSharp/Portable/Binder/Binder.cs b/src/Compilers/CSharp/Portable/Binder/Binder.cs index db19b1ad557e2..73d8f7ae02a5e 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder.cs @@ -216,7 +216,7 @@ internal virtual Symbol ContainingMemberOrLambda /// /// Are we in a context where un-annotated types should be interpreted as non-null? /// - internal Symbol NonNullTypesContext => ContainingMember().OriginalDefinition; + internal INonNullTypesContext NonNullTypesContext => (Flags & BinderFlags.InEEMethodBinder) == 0 ? ContainingMember().OriginalDefinition : NonNullTypesTrueContext.Instance; /// /// Is the contained code within a member method body? diff --git a/src/Compilers/CSharp/Portable/Binder/BinderFlags.cs b/src/Compilers/CSharp/Portable/Binder/BinderFlags.cs index c031a20bca13f..83fbd5752a6e5 100644 --- a/src/Compilers/CSharp/Portable/Binder/BinderFlags.cs +++ b/src/Compilers/CSharp/Portable/Binder/BinderFlags.cs @@ -103,6 +103,11 @@ internal enum BinderFlags : uint /// InContextualAttributeBinder = 1 << 29, + /// + /// Are we binding for the purpose of an Expression Evaluator + /// + InEEMethodBinder = 1 << 30, + // Groups AllClearedAtExecutableCodeBoundary = InLockBody | InCatchBlock | InCatchFilter | InFinallyBlock | InTryBlockOfTryCatch | InNestedFinallyBlock, diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs index e804c3918a752..43d4bb7d5b0ab 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs @@ -1494,28 +1494,22 @@ internal Symbol ResultSymbol( var srcSymbol = symbols[best.Index]; var mdSymbol = symbols[secondBest.Index]; + object arg0; + + if (best.IsFromSourceModule) + { + arg0 = srcSymbol.Locations.First().SourceTree.FilePath; + } + else + { + Debug.Assert(best.IsFromAddedModule); + arg0 = srcSymbol.ContainingModule; + } + //if names match, arities match, and containing symbols match (recursively), ... if (srcSymbol.ToDisplayString(SymbolDisplayFormat.QualifiedNameArityFormat) == mdSymbol.ToDisplayString(SymbolDisplayFormat.QualifiedNameArityFormat)) { - if (srcSymbol.Equals(Compilation.GetWellKnownType(WellKnownType.System_Runtime_CompilerServices_NonNullTypesAttribute))) - { - // Silently prefer the injected symbol - return originalSymbols[best.Index]; - } - - object arg0; - if (best.IsFromSourceModule) - { - SyntaxTree tree = srcSymbol.Locations.FirstOrNone().SourceTree; - arg0 = tree != null ? (object)tree.FilePath : MessageID.IDS_InjectedDeclaration.Localize(); - } - else - { - Debug.Assert(best.IsFromAddedModule); - arg0 = srcSymbol.ContainingModule; - } - if (srcSymbol.Kind == SymbolKind.Namespace && mdSymbol.Kind == SymbolKind.NamedType) { // ErrorCode.WRN_SameFullNameThisNsAgg: The namespace '{1}' in '{0}' conflicts with the imported type '{3}' in '{2}'. Using the namespace defined in '{0}'. diff --git a/src/Compilers/CSharp/Portable/BoundTree/UnboundLambda.cs b/src/Compilers/CSharp/Portable/BoundTree/UnboundLambda.cs index 2401b8ac30c13..075c785850e69 100644 --- a/src/Compilers/CSharp/Portable/BoundTree/UnboundLambda.cs +++ b/src/Compilers/CSharp/Portable/BoundTree/UnboundLambda.cs @@ -499,7 +499,7 @@ private BoundLambda ReallyBind(NamedTypeSymbol delegateType) if (!returnType.IsNull) { - if (returnType.ContainsNullableReferenceTypes()) + if (returnType.NeedsNullableAttribute()) { binder.Compilation.EnsureNullableAttributeExists(diagnostics, lambdaSymbol.DiagnosticLocation, 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 5f4563f3e6979..5df81a6d77ded 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs +++ b/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs @@ -19,7 +19,7 @@ namespace Microsoft.CodeAnalysis.CSharp { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class CSharpResources { @@ -4308,15 +4308,6 @@ internal static string ERR_ExplicitMethodImplAccessor { } } - /// - /// Looks up a localized string similar to Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed.. - /// - internal static string ERR_ExplicitNonNullTypesAttribute { - get { - return ResourceManager.GetString("ERR_ExplicitNonNullTypesAttribute", resourceCulture); - } - } - /// /// Looks up a localized string similar to Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed.. /// @@ -11365,15 +11356,6 @@ internal static string IDS_GlobalNamespace { } } - /// - /// Looks up a localized string similar to injected declaration. - /// - internal static string IDS_InjectedDeclaration { - get { - return ResourceManager.GetString("IDS_InjectedDeclaration", resourceCulture); - } - } - /// /// Looks up a localized string similar to invariantly. /// diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx index 339320c39390f..f7fd13a0408a5 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.resx +++ b/src/Compilers/CSharp/Portable/CSharpResources.resx @@ -4284,9 +4284,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ <text> - - injected declaration - null propagating operator @@ -5628,9 +5625,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ Cannot use a collection of dynamic type in an asynchronous foreach - - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - Expected enable or disable diff --git a/src/Compilers/CSharp/Portable/Emitter/Model/PEAssemblyBuilder.cs b/src/Compilers/CSharp/Portable/Emitter/Model/PEAssemblyBuilder.cs index c633e0f83a93e..7b8299f4b5b98 100644 --- a/src/Compilers/CSharp/Portable/Emitter/Model/PEAssemblyBuilder.cs +++ b/src/Compilers/CSharp/Portable/Emitter/Model/PEAssemblyBuilder.cs @@ -18,13 +18,11 @@ internal abstract class PEAssemblyBuilderBase : PEModuleBuilder, Cci.IAssemblyRe private readonly ImmutableArray _additionalTypes; private ImmutableArray _lazyFiles; + private SynthesizedEmbeddedAttributeSymbol _lazyEmbeddedAttribute; private SynthesizedEmbeddedAttributeSymbol _lazyIsReadOnlyAttribute; private SynthesizedEmbeddedAttributeSymbol _lazyIsByRefLikeAttribute; private SynthesizedEmbeddedAttributeSymbol _lazyIsUnmanagedAttribute; private SynthesizedEmbeddedAttributeSymbol _lazyNullableAttribute; - private ImmutableArray _lazyInjectedTypes; - private bool _needsNonNullTypesAttribute; - private bool _needsEmbeddedAttribute; /// /// The behavior of the C# command-line compiler is as follows: @@ -63,18 +61,6 @@ public PEAssemblyBuilderBase( AssemblyOrModuleSymbolToModuleRefMap.Add(sourceAssembly, this); } - protected override void EnsureNonNullTypesAttributeExists() - { - Debug.Assert(!InjectedSymbolsAreFrozen); - _needsNonNullTypesAttribute = true; - } - - protected override void EnsureEmbeddedAttributeExists() - { - Debug.Assert(!InjectedSymbolsAreFrozen); - _needsEmbeddedAttribute = true; - } - public override ISourceAssemblySymbolInternal SourceAssemblyOpt => _sourceAssembly; internal override ImmutableArray GetAdditionalTopLevelTypes(DiagnosticBag diagnostics) @@ -87,6 +73,10 @@ internal override ImmutableArray GetEmbeddedTypes(DiagnosticBag var builder = ArrayBuilder.GetInstance(); CreateEmbeddedAttributesIfNeeded(diagnostics); + if ((object)_lazyEmbeddedAttribute != null) + { + builder.Add(_lazyEmbeddedAttribute); + } if ((object)_lazyIsReadOnlyAttribute != null) { @@ -182,6 +172,15 @@ protected override void AddEmbeddedResourcesFromAddedModules(ArrayBuilder _sourceAssembly.Identity; public Version AssemblyVersionPattern => _sourceAssembly.AssemblyVersionPattern; + internal override SynthesizedAttributeData SynthesizeEmbeddedAttribute() + { + // _lazyEmbeddedAttribute should have been created before calling this method. + return new SynthesizedAttributeData( + _lazyEmbeddedAttribute.Constructors[0], + ImmutableArray.Empty, + ImmutableArray>.Empty); + } + internal override SynthesizedAttributeData SynthesizeNullableAttribute(WellKnownMember member, ImmutableArray arguments) { if ((object)_lazyNullableAttribute != null) @@ -239,6 +238,8 @@ private void CreateEmbeddedAttributesIfNeeded(DiagnosticBag diagnostics) { if (this.NeedsGeneratedIsReadOnlyAttribute) { + CreateEmbeddedAttributeItselfIfNeeded(diagnostics); + CreateEmbeddedAttributeIfNeeded( ref _lazyIsReadOnlyAttribute, diagnostics, @@ -247,6 +248,8 @@ private void CreateEmbeddedAttributesIfNeeded(DiagnosticBag diagnostics) if (this.NeedsGeneratedIsByRefLikeAttribute) { + CreateEmbeddedAttributeItselfIfNeeded(diagnostics); + CreateEmbeddedAttributeIfNeeded( ref _lazyIsByRefLikeAttribute, diagnostics, @@ -255,6 +258,8 @@ private void CreateEmbeddedAttributesIfNeeded(DiagnosticBag diagnostics) if (this.NeedsGeneratedIsUnmanagedAttribute) { + CreateEmbeddedAttributeItselfIfNeeded(diagnostics); + CreateEmbeddedAttributeIfNeeded( ref _lazyIsUnmanagedAttribute, diagnostics, @@ -263,78 +268,32 @@ private void CreateEmbeddedAttributesIfNeeded(DiagnosticBag diagnostics) if (this.NeedsGeneratedNullableAttribute) { + CreateEmbeddedAttributeItselfIfNeeded(diagnostics); + CreateEmbeddedAttributeIfNeeded( ref _lazyNullableAttribute, diagnostics, AttributeDescription.NullableAttribute, - GetAdditionalNullableAttributeConstructors); + GetNullableAttributeConstructors); } } - protected override bool InjectedSymbolsAreFrozen => !_lazyInjectedTypes.IsDefault; - - /// - /// Get injected types that are needed (ie. were used) and report the diagnostics they held onto (only once). - /// - protected sealed override ImmutableArray GetInjectedTypes(DiagnosticBag diagnostics) + private void CreateEmbeddedAttributeItselfIfNeeded(DiagnosticBag diagnostics) { - if (!_lazyInjectedTypes.IsDefault) - { - return _lazyInjectedTypes; - } - - if (_needsNonNullTypesAttribute) - { - EnsureEmbeddedAttributeExists(); - } - - ArrayBuilder builder = null; - if (_needsEmbeddedAttribute) - { - addInjectedAttribute(WellKnownType.Microsoft_CodeAnalysis_EmbeddedAttribute, canUseFromSource: false); - } - - if (_needsNonNullTypesAttribute) - { - addInjectedAttribute(WellKnownType.System_Runtime_CompilerServices_NonNullTypesAttribute, canUseFromSource: true); - } - - var result = builder is null ? ImmutableArray.Empty : builder.ToImmutableAndFree(); - ImmutableInterlocked.InterlockedInitialize(ref _lazyInjectedTypes, result); - return _lazyInjectedTypes; - - void addInjectedAttribute(WellKnownType wellKnownType, bool canUseFromSource) - { - NamedTypeSymbol attribute = Compilation.GetWellKnownType(wellKnownType); - - if (attribute is InjectedAttributeSymbol injected) - { - injected.AddDiagnostics(diagnostics); - builder = builder ?? ArrayBuilder.GetInstance(); - builder.Add(attribute); - } - else if (attribute.IsErrorType()) - { - diagnostics.Add(attribute.GetUseSiteDiagnostic(), NoLocation.Singleton); - } - else if (!canUseFromSource) - { - // if the attribute is defined in source, we can't embed it (we'll produce a diagnostic) - diagnostics.Add(ErrorCode.ERR_TypeReserved, attribute.Locations[0], attribute); - } - } + CreateEmbeddedAttributeIfNeeded( + ref _lazyEmbeddedAttribute, + diagnostics, + AttributeDescription.CodeAnalysisEmbeddedAttribute); } private void CreateEmbeddedAttributeIfNeeded( ref SynthesizedEmbeddedAttributeSymbol symbol, DiagnosticBag diagnostics, AttributeDescription description, - Func> getAdditionalConstructors = null) + Func> getConstructors = null) { if ((object)symbol == null) { - EnsureEmbeddedAttributeExists(); - var attributeMetadataName = MetadataTypeName.FromFullName(description.FullName); var userDefinedAttribute = _sourceAssembly.SourceModule.LookupTopLevelMetadataType(ref attributeMetadataName); Debug.Assert((object)userDefinedAttribute.ContainingModule == _sourceAssembly.SourceModule); @@ -344,25 +303,28 @@ private void CreateEmbeddedAttributeIfNeeded( diagnostics.Add(ErrorCode.ERR_TypeReserved, userDefinedAttribute.Locations[0], description.FullName); } - symbol = new SynthesizedEmbeddedAttributeSymbol(description, _sourceAssembly.DeclaringCompilation, getAdditionalConstructors, diagnostics); + symbol = new SynthesizedEmbeddedAttributeSymbol(description, _sourceAssembly.DeclaringCompilation, getConstructors, diagnostics); } } - private static ImmutableArray GetAdditionalNullableAttributeConstructors( + private static ImmutableArray GetNullableAttributeConstructors( CSharpCompilation compilation, NamedTypeSymbol containingType, DiagnosticBag diagnostics) { - var boolType = compilation.GetSpecialType(SpecialType.System_Boolean); - Binder.ReportUseSiteDiagnostics(boolType, diagnostics, Location.None); - var boolArray = TypeSymbolWithAnnotations.Create( + var byteType = TypeSymbolWithAnnotations.Create(compilation.GetSpecialType(SpecialType.System_Byte)); + Binder.ReportUseSiteDiagnostics(byteType.TypeSymbol, diagnostics, Location.None); + var byteArray = TypeSymbolWithAnnotations.Create( ArrayTypeSymbol.CreateSZArray( - boolType.ContainingAssembly, - TypeSymbolWithAnnotations.Create(boolType))); + byteType.TypeSymbol.ContainingAssembly, + byteType)); return ImmutableArray.Create( new SynthesizedEmbeddedAttributeConstructorSymbol( containingType, - m => ImmutableArray.Create(SynthesizedParameterSymbol.Create(m, boolArray, 0, RefKind.None)))); + m => ImmutableArray.Create(SynthesizedParameterSymbol.Create(m, byteType, 0, RefKind.None))), + new SynthesizedEmbeddedAttributeConstructorSymbol( + containingType, + m => ImmutableArray.Create(SynthesizedParameterSymbol.Create(m, byteArray, 0, RefKind.None)))); } } diff --git a/src/Compilers/CSharp/Portable/Emitter/Model/PEModuleBuilder.cs b/src/Compilers/CSharp/Portable/Emitter/Model/PEModuleBuilder.cs index 7298e0ec9fa22..39b55bc2f07cb 100644 --- a/src/Compilers/CSharp/Portable/Emitter/Model/PEModuleBuilder.cs +++ b/src/Compilers/CSharp/Portable/Emitter/Model/PEModuleBuilder.cs @@ -43,10 +43,6 @@ public override NoPia.EmbeddedTypesManager EmbeddedTypesManagerOpt private bool _needsGeneratedIsUnmanagedAttribute_Value; private bool _needsGeneratedAttributes_IsFrozen; private bool _needsGeneratedNullableAttribute_Value; - private readonly InjectedNonNullTypesAttributeSymbol _injectedNonNullTypesAttribute; - - protected abstract void EnsureNonNullTypesAttributeExists(); - protected abstract void EnsureEmbeddedAttributeExists(); /// /// Returns a value indicating whether this builder has a symbol that needs IsReadOnlyAttribute to be generated during emit phase. @@ -117,8 +113,6 @@ internal PEModuleBuilder( { _embeddedTypesManagerOpt = new NoPia.EmbeddedTypesManager(this); } - - _injectedNonNullTypesAttribute = Compilation.GetWellKnownType(WellKnownType.System_Runtime_CompilerServices_NonNullTypesAttribute) as InjectedNonNullTypesAttributeSymbol; } public override string Name @@ -455,11 +449,6 @@ internal virtual bool IsEncDelta { namespacesToProcess.Push(memberNamespace); } - else if (member is InjectedAttributeSymbol injectedNonNullTypes) - { - // Skip injected attributes. We'll only embed those that are used. - continue; - } else { var type = (NamedTypeSymbol)member; @@ -953,11 +942,6 @@ internal Cci.INamedTypeReference Translate( } } - if (!InjectedSymbolsAreFrozen && namedTypeSymbol.Equals(_injectedNonNullTypesAttribute)) - { - EnsureNonNullTypesAttributeExists(); - } - // NoPia: See if this is a type, which definition we should copy into our assembly. Debug.Assert(namedTypeSymbol.IsDefinition); @@ -1461,6 +1445,8 @@ protected override Cci.IMethodDefinition CreatePrivateImplementationDetailsStati return new SynthesizedPrivateImplementationDetailsStaticConstructor(SourceModule, details, GetUntranslatedSpecialType(SpecialType.System_Void, syntaxOpt, diagnostics)); } + internal abstract SynthesizedAttributeData SynthesizeEmbeddedAttribute(); + internal SynthesizedAttributeData SynthesizeIsReadOnlyAttribute(Symbol symbol) { if ((object)Compilation.SourceModule != symbol.ContainingModule) @@ -1507,34 +1493,34 @@ internal SynthesizedAttributeData SynthesizeNullableAttribute(Symbol symbol, Typ return null; } - var flagsBuilder = ArrayBuilder.GetInstance(); + var flagsBuilder = ArrayBuilder.GetInstance(); type.AddNullableTransforms(flagsBuilder); Debug.Assert(flagsBuilder.Any()); - Debug.Assert(flagsBuilder.Contains(true)); + Debug.Assert(flagsBuilder.Contains((byte)NullableAnnotation.NotNullable) || flagsBuilder.Contains((byte)NullableAnnotation.Nullable)); WellKnownMember constructor; ImmutableArray arguments; + NamedTypeSymbol byteType = Compilation.GetSpecialType(SpecialType.System_Byte); + Debug.Assert((object)byteType != null); - if (flagsBuilder.Count == 1 && flagsBuilder[0]) + if (flagsBuilder.All(flag => flag == (byte)NullableAnnotation.NotNullable) || flagsBuilder.All(flag => flag == (byte)NullableAnnotation.Nullable)) { - constructor = WellKnownMember.System_Runtime_CompilerServices_NullableAttribute__ctor; - arguments = ImmutableArray.Empty; + constructor = WellKnownMember.System_Runtime_CompilerServices_NullableAttribute__ctorByte; + arguments = ImmutableArray.Create(new TypedConstant(byteType, TypedConstantKind.Primitive, flagsBuilder[0])); } else { - NamedTypeSymbol booleanType = Compilation.GetSpecialType(SpecialType.System_Boolean); - Debug.Assert((object)booleanType != null); var constantsBuilder = ArrayBuilder.GetInstance(flagsBuilder.Count); - foreach (bool flag in flagsBuilder) + foreach (byte flag in flagsBuilder) { - constantsBuilder.Add(new TypedConstant(booleanType, TypedConstantKind.Primitive, flag)); + constantsBuilder.Add(new TypedConstant(byteType, TypedConstantKind.Primitive, flag)); } - var boolArray = ArrayTypeSymbol.CreateSZArray(booleanType.ContainingAssembly, TypeSymbolWithAnnotations.Create(booleanType)); + var byteArray = ArrayTypeSymbol.CreateSZArray(byteType.ContainingAssembly, TypeSymbolWithAnnotations.Create(byteType)); constructor = WellKnownMember.System_Runtime_CompilerServices_NullableAttribute__ctorTransformFlags; - arguments = ImmutableArray.Create(new TypedConstant(boolArray, constantsBuilder.ToImmutableAndFree())); + arguments = ImmutableArray.Create(new TypedConstant(byteArray, constantsBuilder.ToImmutableAndFree())); } flagsBuilder.Free(); diff --git a/src/Compilers/CSharp/Portable/Emitter/Model/PENetModuleBuilder.cs b/src/Compilers/CSharp/Portable/Emitter/Model/PENetModuleBuilder.cs index f7a54b83e75fa..dc29115069cd9 100644 --- a/src/Compilers/CSharp/Portable/Emitter/Model/PENetModuleBuilder.cs +++ b/src/Compilers/CSharp/Portable/Emitter/Model/PENetModuleBuilder.cs @@ -21,6 +21,12 @@ internal PENetModuleBuilder( { } + internal override SynthesizedAttributeData SynthesizeEmbeddedAttribute() + { + // Embedded attributes should never be synthesized in modules. + throw ExceptionUtilities.Unreachable; + } + protected override void AddEmbeddedResourcesFromAddedModules(ArrayBuilder builder, DiagnosticBag diagnostics) { throw ExceptionUtilities.Unreachable; @@ -29,10 +35,5 @@ protected override void AddEmbeddedResourcesFromAddedModules(ArrayBuilder 0; public override IEnumerable GetFiles(EmitContext context) => SpecializedCollections.EmptyEnumerable(); public override ISourceAssemblySymbolInternal SourceAssemblyOpt => null; - - protected override void EnsureNonNullTypesAttributeExists() => throw ExceptionUtilities.Unreachable; - protected override void EnsureEmbeddedAttributeExists() => throw ExceptionUtilities.Unreachable; - protected override ImmutableArray GetInjectedTypes(DiagnosticBag diagnostics) => ImmutableArray.Empty; - protected override bool InjectedSymbolsAreFrozen => true; } } diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs index 55f1f82c99538..3c74fe1af97c7 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs @@ -1631,7 +1631,7 @@ internal enum ErrorCode WRN_NullabilityMismatchInConstraintsOnImplicitImplementation = 8633, WRN_NullabilityMismatchInTypeParameterReferenceTypeConstraint = 8634, ERR_TripleDotNotAllowed = 8635, - ERR_ExplicitNonNullTypesAttribute = 8636, + // Available -> 8636, ERR_NullableDirectiveQualifierExpected = 8637, WRN_CantInferNullabilityOfMethodTypeArgs = 8638, WRN_NoBestNullabilityArrayElements = 8639, diff --git a/src/Compilers/CSharp/Portable/Errors/MessageID.cs b/src/Compilers/CSharp/Portable/Errors/MessageID.cs index a28ea45ecbd89..8364932ee5706 100644 --- a/src/Compilers/CSharp/Portable/Errors/MessageID.cs +++ b/src/Compilers/CSharp/Portable/Errors/MessageID.cs @@ -165,11 +165,10 @@ internal enum MessageID IDS_FeatureAltInterpolatedVerbatimStrings = MessageBase + 12745, IDS_FeatureCoalesceAssignmentExpression = MessageBase + 12746, IDS_FeatureUnconstrainedTypeParameterInNullCoalescingOperator = MessageBase + 12747, - IDS_InjectedDeclaration = MessageBase + 12748, - IDS_FeatureObjectGenericTypeConstraint = MessageBase + 12749, - IDS_FeatureIndexOperator = MessageBase + 12750, - IDS_FeatureRangeOperator = MessageBase + 12751, - IDS_FeatureAsyncStreams = MessageBase + 12752, + IDS_FeatureObjectGenericTypeConstraint = MessageBase + 12748, + IDS_FeatureIndexOperator = MessageBase + 12749, + IDS_FeatureRangeOperator = MessageBase + 12750, + IDS_FeatureAsyncStreams = MessageBase + 12751, } // Message IDs may refer to strings that need to be localized. diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs index 59270a46b3e20..16ffee9aec2a0 100644 --- a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs +++ b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs @@ -269,16 +269,17 @@ private void Populate(ref LocalState state, int start) int capacity = state.Capacity; for (int slot = start; slot < capacity; slot++) { - var value = GetDefaultState(ref state, slot); + (NullableAnnotation value, bool assigned) = GetDefaultState(ref state, slot); state[slot] = value; + state.SetAssigned(slot, assigned); } } - private NullableAnnotation GetDefaultState(ref LocalState state, int slot) + private (NullableAnnotation annotation, bool assigned) GetDefaultState(ref LocalState state, int slot) { if (slot == 0) { - return NullableAnnotation.Unknown; + return (NullableAnnotation.Unknown, false); } var variable = variableBySlot[slot]; @@ -287,35 +288,35 @@ private NullableAnnotation GetDefaultState(ref LocalState state, int slot) switch (symbol.Kind) { case SymbolKind.Local: - return NullableAnnotation.Unknown; + return (NullableAnnotation.Unknown, false); case SymbolKind.Parameter: { var parameter = (ParameterSymbol)symbol; if (parameter.RefKind == RefKind.Out) { - return NullableAnnotation.Unknown; + return (NullableAnnotation.Unknown, false); } TypeSymbolWithAnnotations parameterType; if (!_variableTypes.TryGetValue(parameter, out parameterType)) { parameterType = parameter.Type; } - return parameterType.NullableAnnotation; + + return (parameterType.NullableAnnotation, true); } case SymbolKind.Field: case SymbolKind.Property: case SymbolKind.Event: { - // https://github.com/dotnet/roslyn/issues/30065 State of containing struct should not be important. - // And if it is important, what about fields of structs that are fields of other structs, etc.? int containingSlot = variable.ContainingSlot; if (containingSlot > 0 && variableBySlot[containingSlot].Symbol.GetTypeOrReturnType().TypeKind == TypeKind.Struct && - state[containingSlot] == NullableAnnotation.Unknown) + !state.IsAssigned(containingSlot)) { - return NullableAnnotation.Unknown; + return (NullableAnnotation.Unknown, false); } - return symbol.GetTypeOrReturnType().NullableAnnotation; + + return (symbol.GetTypeOrReturnType().NullableAnnotation, true); } default: throw ExceptionUtilities.UnexpectedValue(symbol.Kind); @@ -814,19 +815,19 @@ private void InheritNullableStateOfTrackableType(int targetSlot, int valueSlot, protected override LocalState ReachableState() { - var state = new LocalState(reachable: true, new ArrayBuilder(nextVariableSlot)); + var state = new LocalState(reachable: true, BitVector.Create(nextVariableSlot), new ArrayBuilder(nextVariableSlot)); Populate(ref state, start: 0); return state; } protected override LocalState UnreachableState() { - return new LocalState(reachable: false, null); + return new LocalState(reachable: false, BitVector.Empty, null); } protected override LocalState AllBitsSet() { - return new LocalState(reachable: true, new ArrayBuilder(nextVariableSlot)); + return new LocalState(reachable: true, BitVector.AllSet(nextVariableSlot), new ArrayBuilder(nextVariableSlot)); } private void EnterParameters() @@ -4632,6 +4633,13 @@ protected override void UnionWith(ref LocalState self, ref LocalState other) { self[slot] = union; } + + bool selfIsAssigned = self.IsAssigned(slot); + bool isAssigned = selfIsAssigned || other.IsAssigned(slot); + if (selfIsAssigned != isAssigned) + { + self.SetAssigned(slot, isAssigned); + } } } @@ -4707,6 +4715,14 @@ protected override bool IntersectWith(ref LocalState self, ref LocalState other) self[slot] = intersection; result = true; } + + bool selfIsAssigned = self.IsAssigned(slot); + bool isAssigned = selfIsAssigned && other.IsAssigned(slot); + if (selfIsAssigned != isAssigned) + { + self.SetAssigned(slot, isAssigned); + result = true; + } } return result; @@ -4736,12 +4752,15 @@ internal class LocalState : AbstractLocalState internal struct LocalState : AbstractLocalState #endif { + private BitVector _assigned; private ArrayBuilder _state; public bool Reachable { get; } - internal LocalState(bool reachable, ArrayBuilder state) + internal LocalState(bool reachable, BitVector assigned, ArrayBuilder state) { + Debug.Assert(!assigned.IsNull); this.Reachable = reachable; + this._assigned = assigned; this._state = state; } @@ -4749,6 +4768,8 @@ internal LocalState(bool reachable, ArrayBuilder state) internal void EnsureCapacity(int capacity) { + _assigned.EnsureCapacity(capacity); + if (_state == null) { _state = new ArrayBuilder(capacity); @@ -4775,9 +4796,20 @@ internal NullableAnnotation this[int slot] { EnsureCapacity(slot + 1); _state[slot] = value; + SetAssigned(slot, true); } } + internal void SetAssigned(int slot, bool value) + { + _assigned[slot] = value; + } + + internal bool IsAssigned(int slot) + { + return _assigned[slot]; + } + /// /// Produce a duplicate of this flow analysis state. /// @@ -4797,7 +4829,7 @@ public LocalState Clone() clone.AddRange(_state); } - return new LocalState(Reachable, clone); + return new LocalState(Reachable, _assigned.Clone(), clone); } internal string GetDebuggerDisplay() diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter.cs index e664171430cb3..8259c6948c80f 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter.cs @@ -244,15 +244,15 @@ public override BoundNode VisitLocalFunctionStatement(BoundLocalFunctionStatemen _factory.CompilationState.ModuleBuilderOpt?.EnsureIsUnmanagedAttributeExists(); } - bool hasConstraintsWithNullableReferenceTypes = typeParameters.Any( - typeParameter => typeParameter.ReferenceTypeConstraintIsNullable == true || + bool constraintsNeedNullableAttribute = typeParameters.Any( + typeParameter => (typeParameter.HasReferenceTypeConstraint && typeParameter.ReferenceTypeConstraintIsNullable != null) || typeParameter.ConstraintTypesNoUseSiteDiagnostics.Any( - typeConstraint => typeConstraint.ContainsNullableReferenceTypes())); + typeConstraint => typeConstraint.NeedsNullableAttribute())); - bool hasReturnTypeWithNullableReferenceTypes = node.Symbol.ReturnType.ContainsNullableReferenceTypes(); - bool hasParametersWithNullableReferenceTypes = node.Symbol.ParameterTypes.Any(parameter => parameter.ContainsNullableReferenceTypes()); + bool returnTypeNeedsNullableAttribute = node.Symbol.ReturnType.NeedsNullableAttribute(); + bool parametersNeedNullableAttribute = node.Symbol.ParameterTypes.Any(parameter => parameter.NeedsNullableAttribute()); - if (hasConstraintsWithNullableReferenceTypes || hasReturnTypeWithNullableReferenceTypes || hasParametersWithNullableReferenceTypes) + if (constraintsNeedNullableAttribute || returnTypeNeedsNullableAttribute || parametersNeedNullableAttribute) { _factory.CompilationState.ModuleBuilderOpt?.EnsureNullableAttributeExists(); } diff --git a/src/Compilers/CSharp/Portable/Symbols/ArrayTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/ArrayTypeSymbol.cs index 7ca8893987b84..b8d0a424665af 100644 --- a/src/Compilers/CSharp/Portable/Symbols/ArrayTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/ArrayTypeSymbol.cs @@ -379,17 +379,17 @@ public override int GetHashCode() return Hash.Combine(current, hash); } - internal override void AddNullableTransforms(ArrayBuilder transforms) + internal override void AddNullableTransforms(ArrayBuilder transforms) { ElementType.AddNullableTransforms(transforms); } - internal override bool ApplyNullableTransforms(ImmutableArray transforms, INonNullTypesContext nonNullTypesContext, ref int position, out TypeSymbol result) + internal override bool ApplyNullableTransforms(byte defaultTransformFlag, ImmutableArray transforms, ref int position, out TypeSymbol result) { TypeSymbolWithAnnotations oldElementType = ElementType; TypeSymbolWithAnnotations newElementType; - if (!oldElementType.ApplyNullableTransforms(transforms, nonNullTypesContext, ref position, out newElementType)) + if (!oldElementType.ApplyNullableTransforms(defaultTransformFlag, transforms, ref position, out newElementType)) { result = this; return false; diff --git a/src/Compilers/CSharp/Portable/Symbols/Compilation_WellKnownMembers.cs b/src/Compilers/CSharp/Portable/Symbols/Compilation_WellKnownMembers.cs index a76ddfdace1ca..d27a2ddec426b 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Compilation_WellKnownMembers.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Compilation_WellKnownMembers.cs @@ -166,14 +166,10 @@ internal NamedTypeSymbol GetWellKnownType(WellKnownType type) } else { - // Well-known types that are injected cannot be referenced from another assembly - bool includeReferences = type != WellKnownType.System_Runtime_CompilerServices_NonNullTypesAttribute && - type != WellKnownType.Microsoft_CodeAnalysis_EmbeddedAttribute; - // well-known types introduced before CSharp7 allow lookup ambiguity and report a warning DiagnosticBag legacyWarnings = (type <= WellKnownType.CSharp7Sentinel) ? warnings : null; result = this.Assembly.GetTypeByMetadataName( - mdName, includeReferences: includeReferences, useCLSCompliantNameArityEncoding: true, isWellKnownType: true, conflicts: out conflicts, + mdName, includeReferences: true, useCLSCompliantNameArityEncoding: true, isWellKnownType: true, conflicts: out conflicts, warnings: legacyWarnings, ignoreCorLibraryDuplicatedTypes: ignoreCorLibraryDuplicatedTypes); } @@ -447,13 +443,6 @@ internal SynthesizedAttributeData TrySynthesizeAttribute( return new SynthesizedAttributeData(ctorSymbol, arguments, namedStringArguments); } - internal SynthesizedAttributeData TrySynthesizeNonNullTypesAttribute(bool value) - { - return TrySynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_NonNullTypesAttribute__ctor, - ImmutableArray.Create(new TypedConstant(GetSpecialType(SpecialType.System_Boolean), TypedConstantKind.Primitive, value)), - isOptionalUse: true); - } - internal SynthesizedAttributeData SynthesizeDecimalConstantAttribute(decimal value) { bool isNegative; @@ -583,7 +572,7 @@ internal bool CheckIfNullableAttributeShouldBeEmbedded(DiagnosticBag diagnostics diagnosticsOpt, locationOpt, WellKnownType.System_Runtime_CompilerServices_NullableAttribute, - WellKnownMember.System_Runtime_CompilerServices_NullableAttribute__ctor, + WellKnownMember.System_Runtime_CompilerServices_NullableAttribute__ctorByte, WellKnownMember.System_Runtime_CompilerServices_NullableAttribute__ctorTransformFlags); } diff --git a/src/Compilers/CSharp/Portable/Symbols/DynamicTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/DynamicTypeSymbol.cs index a9525f3c2f8b6..b6f11481b887c 100644 --- a/src/Compilers/CSharp/Portable/Symbols/DynamicTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/DynamicTypeSymbol.cs @@ -217,11 +217,11 @@ internal override bool Equals(TypeSymbol t2, TypeCompareKind comparison) return false; } - internal override void AddNullableTransforms(ArrayBuilder transforms) + internal override void AddNullableTransforms(ArrayBuilder transforms) { } - internal override bool ApplyNullableTransforms(ImmutableArray transforms, INonNullTypesContext nonNullTypesContext, ref int position, out TypeSymbol result) + internal override bool ApplyNullableTransforms(byte defaultTransformFlag, ImmutableArray transforms, ref int position, out TypeSymbol result) { result = this; return true; diff --git a/src/Compilers/CSharp/Portable/Symbols/ExtraAnnotations.cs b/src/Compilers/CSharp/Portable/Symbols/ExtraAnnotations.cs index bda6f3322adb0..67249ab52f4eb 100644 --- a/src/Compilers/CSharp/Portable/Symbols/ExtraAnnotations.cs +++ b/src/Compilers/CSharp/Portable/Symbols/ExtraAnnotations.cs @@ -19,8 +19,8 @@ internal static class ExtraAnnotations // 1) don't accept null input // 2) return a reference type // All types in a member which can be annotated should be annotated. Value types and void can be skipped (with a `default`) - private static readonly ImmutableDictionary>> Annotations = - new Dictionary>> + private static readonly ImmutableDictionary>> Annotations = + new Dictionary>> { { "System.Boolean System.Boolean.Parse(System.String)", Array(default, Nullable(false)) }, { "System.Void System.Buffer.BlockCopy(System.Array, System.Int32, System.Array, System.Int32, System.Int32)", Array(default, Nullable(false), default, Nullable(false), default, default) }, @@ -121,19 +121,18 @@ internal static string MakeMethodKey(MethodSymbol method) // use assembly qualified name format (used in metadata) rather than symbol display? } - private static ImmutableArray> Array(params ImmutableArray[] values) + private static ImmutableArray> Array(params ImmutableArray[] values) => values.ToImmutableArray(); private static ImmutableArray Array(params FlowAnalysisAnnotations[] values) => values.ToImmutableArray(); - private static ImmutableArray Nullable(params bool[] values) + private static ImmutableArray Nullable(bool isNullable) { - Debug.Assert(values.Length > 0); - return values.ToImmutableArray(); + return ImmutableArray.Create((byte)(isNullable ? NullableAnnotation.Nullable : NullableAnnotation.NotNullable)); } - internal static ImmutableArray> GetExtraAnnotations(string key) + internal static ImmutableArray> GetExtraAnnotations(string key) { if (key is null) { diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/NullableTypeDecoder.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/NullableTypeDecoder.cs index ca1c905f5a944..6ab9e768aecba 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/NullableTypeDecoder.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/NullableTypeDecoder.cs @@ -16,22 +16,27 @@ internal static class NullableTypeDecoder internal static TypeSymbolWithAnnotations TransformType( TypeSymbolWithAnnotations metadataType, EntityHandle targetSymbolToken, - PEModuleSymbol containingModule, - INonNullTypesContext nonNullTypesContext) + PEModuleSymbol containingModule) { Debug.Assert(!metadataType.IsNull); - ImmutableArray nullableTransformFlags; - containingModule.Module.HasNullableAttribute(targetSymbolToken, out nullableTransformFlags); + byte defaultTransformFlag; + ImmutableArray nullableTransformFlags; + containingModule.Module.HasNullableAttribute(targetSymbolToken, out defaultTransformFlag, out nullableTransformFlags); - return TransformType(metadataType, nullableTransformFlags, nonNullTypesContext); + return TransformType(metadataType, defaultTransformFlag, nullableTransformFlags); } - internal static TypeSymbolWithAnnotations TransformType(TypeSymbolWithAnnotations metadataType, ImmutableArray nullableTransformFlags, INonNullTypesContext nonNullTypesContext) + internal static TypeSymbolWithAnnotations TransformType(TypeSymbolWithAnnotations metadataType, byte defaultTransformFlag, ImmutableArray nullableTransformFlags) { + if (nullableTransformFlags.IsDefault && defaultTransformFlag == 0) + { + return metadataType; + } + int position = 0; TypeSymbolWithAnnotations result; - if (metadataType.ApplyNullableTransforms(nullableTransformFlags, nonNullTypesContext, ref position, out result) && + if (metadataType.ApplyNullableTransforms(defaultTransformFlag, nullableTransformFlags, ref position, out result) && (nullableTransformFlags.IsDefault || position == nullableTransformFlags.Length)) { return result; @@ -46,16 +51,15 @@ internal static TypeSymbolWithAnnotations TransformType( TypeSymbolWithAnnotations metadataType, EntityHandle targetSymbolToken, PEModuleSymbol containingModule, - INonNullTypesContext nonNullTypesContext, - ImmutableArray extraAnnotations) + ImmutableArray extraAnnotations) { if (extraAnnotations.IsDefault) { - return NullableTypeDecoder.TransformType(metadataType, targetSymbolToken, containingModule, nonNullTypesContext); + return NullableTypeDecoder.TransformType(metadataType, targetSymbolToken, containingModule); } else { - return NullableTypeDecoder.TransformType(metadataType, extraAnnotations, NonNullTypesTrueContext.Instance); + return NullableTypeDecoder.TransformType(metadataType, defaultTransformFlag: 0, extraAnnotations); } } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEEventSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEEventSymbol.cs index ddd88fe4d1715..883b62712a809 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEEventSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEEventSymbol.cs @@ -84,7 +84,7 @@ internal PEEventSymbol( if (eventType.IsNil) { - _eventType = TypeSymbolWithAnnotations.Create(containingType, new UnsupportedMetadataTypeSymbol(mrEx)); + _eventType = TypeSymbolWithAnnotations.Create(new UnsupportedMetadataTypeSymbol(mrEx)); } } @@ -98,11 +98,11 @@ internal PEEventSymbol( var typeSymbol = DynamicTypeDecoder.TransformType(originalEventType, targetSymbolCustomModifierCount, handle, moduleSymbol); // We start without annotation (they will be decoded below) - var type = TypeSymbolWithAnnotations.Create(nonNullTypesContext: containingType, typeSymbol); + var type = TypeSymbolWithAnnotations.Create(typeSymbol); // Decode nullable before tuple types to avoid converting between // NamedTypeSymbol and TupleTypeSymbol unnecessarily. - type = NullableTypeDecoder.TransformType(type, handle, moduleSymbol, nonNullTypesContext: this); + type = NullableTypeDecoder.TransformType(type, handle, moduleSymbol); type = TupleTypeDecoder.DecodeTupleTypesIfApplicable(type, handle, moduleSymbol); _eventType = type; } @@ -478,10 +478,7 @@ public override bool? NonNullTypes { get { - var moduleSymbol = _containingType.ContainingPEModule; - bool optOut; - - return moduleSymbol.Module.HasNonNullTypesAttribute(_handle, out optOut) ? optOut : base.NonNullTypes; + throw ExceptionUtilities.Unreachable; } } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEFieldSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEFieldSymbol.cs index 7bc5b7b5c422d..3e52ae3197ff7 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEFieldSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEFieldSymbol.cs @@ -214,11 +214,11 @@ private void EnsureSignatureIsLoaded() typeSymbol = DynamicTypeDecoder.TransformType(typeSymbol, customModifiersArray.Length, _handle, moduleSymbol); // We start without annotations - var type = TypeSymbolWithAnnotations.Create(nonNullTypesContext: this, typeSymbol, customModifiers: customModifiersArray); + var type = TypeSymbolWithAnnotations.Create(typeSymbol, customModifiers: customModifiersArray); // Decode nullable before tuple types to avoid converting between // NamedTypeSymbol and TupleTypeSymbol unnecessarily. - type = NullableTypeDecoder.TransformType(type, _handle, moduleSymbol, nonNullTypesContext: this); + type = NullableTypeDecoder.TransformType(type, _handle, moduleSymbol); type = TupleTypeDecoder.DecodeTupleTypesIfApplicable(type, _handle, moduleSymbol); _lazyIsVolatile = isVolatile; @@ -511,10 +511,7 @@ public override bool? NonNullTypes { get { - var moduleSymbol = _containingType.ContainingPEModule; - bool optOut; - - return moduleSymbol.Module.HasNonNullTypesAttribute(_handle, out optOut) ? optOut : base.NonNullTypes; + throw ExceptionUtilities.Unreachable; } } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEMethodSymbol.cs index 2bc03136be22b..ff03b941d5a36 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEMethodSymbol.cs @@ -583,7 +583,7 @@ private SignatureData LoadSignature() bool isBadParameter; string key = ExtraAnnotations.MakeMethodKey(this, paramInfo); - ImmutableArray> extraMethodAnnotations = ExtraAnnotations.GetExtraAnnotations(key); + ImmutableArray> extraMethodAnnotations = ExtraAnnotations.GetExtraAnnotations(key); if (count > 0) { @@ -591,7 +591,7 @@ private SignatureData LoadSignature() for (int i = 0; i < count; i++) { // zero-th annotation is for the return type - ImmutableArray extraAnnotations = extraMethodAnnotations.IsDefault ? default : extraMethodAnnotations[i + 1]; + ImmutableArray extraAnnotations = extraMethodAnnotations.IsDefault ? default : extraMethodAnnotations[i + 1]; builder.Add(PEParameterSymbol.Create( moduleSymbol, this, this.IsMetadataVirtual(), i, @@ -615,7 +615,7 @@ private SignatureData LoadSignature() paramInfo[0].Type = returnType; - ImmutableArray extraReturnAnnotations = extraMethodAnnotations.IsDefault ? default : extraMethodAnnotations[0]; + ImmutableArray extraReturnAnnotations = extraMethodAnnotations.IsDefault ? default : extraMethodAnnotations[0]; var returnParam = PEParameterSymbol.Create( moduleSymbol, this, this.IsMetadataVirtual(), 0, paramInfo[0], extraReturnAnnotations, isReturn: true, out isBadParameter); @@ -715,9 +715,7 @@ public override bool? NonNullTypes { get { - var moduleSymbol = _containingType.ContainingPEModule; - bool nonNullTypes; - return moduleSymbol.Module.HasNonNullTypesAttribute(_handle, out nonNullTypes) ? nonNullTypes : base.NonNullTypes; + throw ExceptionUtilities.Unreachable; } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEModuleSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEModuleSymbol.cs index a8992cb349e01..7425742ddb627 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEModuleSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEModuleSymbol.cs @@ -701,7 +701,7 @@ public override bool? NonNullTypes { get { - return _module.HasNonNullTypesAttribute(EntityHandle.ModuleDefinition, out bool nonNullTypes) ? (bool?)nonNullTypes : null; + throw ExceptionUtilities.Unreachable; } } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PENamedTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PENamedTypeSymbol.cs index 9464afffd3fec..45f02313843f7 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PENamedTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PENamedTypeSymbol.cs @@ -448,7 +448,7 @@ private NamedTypeSymbol GetDeclaredBaseType(bool ignoreNullability) if ((object)declaredBase != null) { declaredBase = (NamedTypeSymbol)NullableTypeDecoder.TransformType( - TypeSymbolWithAnnotations.Create(nonNullTypesContext: this, declaredBase), _handle, ContainingPEModule, nonNullTypesContext: this).TypeSymbol; + TypeSymbolWithAnnotations.Create(declaredBase), _handle, ContainingPEModule).TypeSymbol; } Interlocked.CompareExchange(ref _lazyDeclaredBaseTypeWithNullability, declaredBase, ErrorTypeSymbol.UnknownResultType); } @@ -511,7 +511,7 @@ private ImmutableArray MakeDeclaredInterfaces() TypeSymbol typeSymbol = tokenDecoder.GetTypeOfToken(interfaceHandle); typeSymbol = TupleTypeDecoder.DecodeTupleTypesIfApplicable(typeSymbol, interfaceImpl, moduleSymbol); - typeSymbol = NullableTypeDecoder.TransformType(TypeSymbolWithAnnotations.Create(nonNullTypesContext: this, typeSymbol), interfaceImpl, moduleSymbol, nonNullTypesContext: this).TypeSymbol; + typeSymbol = NullableTypeDecoder.TransformType(TypeSymbolWithAnnotations.Create(typeSymbol), interfaceImpl, moduleSymbol).TypeSymbol; var namedTypeSymbol = typeSymbol as NamedTypeSymbol ?? new UnsupportedMetadataTypeSymbol(); // interface list contains a bad type symbols.Add(namedTypeSymbol); @@ -1990,8 +1990,7 @@ public override bool? NonNullTypes { get { - bool nonNullTypes; - return this.ContainingPEModule.Module.HasNonNullTypesAttribute(_handle, out nonNullTypes) ? nonNullTypes : base.NonNullTypes; + throw ExceptionUtilities.Unreachable; } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEParameterSymbol.cs index 31c5cd16ed037..a7f8e984a29dd 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEParameterSymbol.cs @@ -148,7 +148,7 @@ internal static PEParameterSymbol Create( bool isContainingSymbolVirtual, int ordinal, ParamInfo parameterInfo, - ImmutableArray extraAnnotations, + ImmutableArray extraAnnotations, bool isReturn, out bool isBad) { @@ -176,7 +176,7 @@ internal static PEParameterSymbol Create( int ordinal, ParameterHandle handle, ParamInfo parameterInfo, - ImmutableArray extraAnnotations, + ImmutableArray extraAnnotations, out bool isBad) { return Create( @@ -191,7 +191,7 @@ private PEParameterSymbol( int ordinal, bool isByRef, TypeSymbolWithAnnotations type, - ImmutableArray extraAnnotations, + ImmutableArray extraAnnotations, ParameterHandle handle, int countOfCustomModifiers, out bool isBad) @@ -219,8 +219,7 @@ private PEParameterSymbol( type; if (!extraAnnotations.IsDefault) { - // https://github.com/dotnet/roslyn/issues/29821 any external annotation is taken to imply a `[NonNullTypes(true)]` context - type = NullableTypeDecoder.TransformType(type, extraAnnotations, nonNullTypesContext: NonNullTypesTrueContext.Instance); + type = NullableTypeDecoder.TransformType(type, defaultTransformFlag: 0, extraAnnotations); } _lazyCustomAttributes = ImmutableArray.Empty; @@ -262,7 +261,7 @@ private PEParameterSymbol( type = type.WithTypeAndModifiers(typeSymbol, type.CustomModifiers); // Decode nullable before tuple types to avoid converting between // NamedTypeSymbol and TupleTypeSymbol unnecessarily. - type = NullableTypeDecoder.TransformType(type, handle, moduleSymbol, nonNullTypesContext: this, extraAnnotations); + type = NullableTypeDecoder.TransformType(type, handle, moduleSymbol, extraAnnotations); type = TupleTypeDecoder.DecodeTupleTypesIfApplicable(type, handle, moduleSymbol); } @@ -297,14 +296,14 @@ private static PEParameterSymbol Create( bool isByRef, ImmutableArray> refCustomModifiers, TypeSymbol type, - ImmutableArray extraAnnotations, + ImmutableArray extraAnnotations, ParameterHandle handle, ImmutableArray> customModifiers, bool isReturn, out bool isBad) { // We start without annotation (they will be decoded below) - var typeWithModifiers = TypeSymbolWithAnnotations.Create(containingSymbol, type, customModifiers: CSharpCustomModifier.Convert(customModifiers)); + var typeWithModifiers = TypeSymbolWithAnnotations.Create(type, customModifiers: CSharpCustomModifier.Convert(customModifiers)); PEParameterSymbol parameter = customModifiers.IsDefaultOrEmpty && refCustomModifiers.IsDefaultOrEmpty ? new PEParameterSymbol(moduleSymbol, containingSymbol, ordinal, isByRef, typeWithModifiers, extraAnnotations, handle, 0, out isBad) @@ -342,7 +341,7 @@ public PEParameterSymbolWithCustomModifiers( bool isByRef, ImmutableArray> refCustomModifiers, TypeSymbolWithAnnotations type, - ImmutableArray extraAnnotations, + ImmutableArray extraAnnotations, ParameterHandle handle, out bool isBad) : base(moduleSymbol, containingSymbol, ordinal, isByRef, type, extraAnnotations, handle, diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEPropertySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEPropertySymbol.cs index 059cf3413ac5a..3473c8b20e6b2 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEPropertySymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEPropertySymbol.cs @@ -12,6 +12,7 @@ using Microsoft.CodeAnalysis.CSharp.DocumentationComments; using Microsoft.CodeAnalysis.CSharp.Emit; using Microsoft.CodeAnalysis.PooledObjects; +using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE { @@ -167,11 +168,11 @@ private PEPropertySymbol( originalPropertyType = originalPropertyType.AsDynamicIfNoPia(_containingType); // We start without annotation (they will be decoded below) - var propertyType = TypeSymbolWithAnnotations.Create(nonNullTypesContext: this, originalPropertyType, isAnnotated: false, typeCustomModifiers); + var propertyType = TypeSymbolWithAnnotations.Create(originalPropertyType, customModifiers: typeCustomModifiers); // Decode nullable before tuple types to avoid converting between // NamedTypeSymbol and TupleTypeSymbol unnecessarily. - propertyType = NullableTypeDecoder.TransformType(propertyType, handle, moduleSymbol, nonNullTypesContext: this); + propertyType = NullableTypeDecoder.TransformType(propertyType, handle, moduleSymbol); propertyType = TupleTypeDecoder.DecodeTupleTypesIfApplicable(propertyType, handle, moduleSymbol); _propertyType = propertyType; @@ -738,9 +739,7 @@ public override bool? NonNullTypes { get { - var moduleSymbol = _containingType.ContainingPEModule; - bool nonNullTypes; - return moduleSymbol.Module.HasNonNullTypesAttribute(_handle, out nonNullTypes) ? nonNullTypes : base.NonNullTypes; + throw ExceptionUtilities.Unreachable; } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PETypeParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PETypeParameterSymbol.cs index e54e050210182..d400dd0723d14 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PETypeParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PETypeParameterSymbol.cs @@ -206,9 +206,8 @@ private ImmutableArray GetDeclaredConstraintTypes() } } - // https://github.com/dotnet/roslyn/issues/30075: Test different [NonNullTypes] on method and containing type. - var type = TypeSymbolWithAnnotations.Create(this, typeSymbol); - type = NullableTypeDecoder.TransformType(type, constraintHandle, moduleSymbol, nonNullTypesContext: this); + var type = TypeSymbolWithAnnotations.Create(typeSymbol); + type = NullableTypeDecoder.TransformType(type, constraintHandle, moduleSymbol); // Drop 'System.Object?' constraint type. if (type.SpecialType == SpecialType.System_Object && type.NullableAnnotation.IsAnyNullable()) @@ -287,15 +286,15 @@ internal override bool? ReferenceTypeConstraintIsNullable return false; } - if (((PEModuleSymbol)this.ContainingModule).Module.HasNullableAttribute(_handle, out ImmutableArray nullableTransformFlags) && - nullableTransformFlags.Length == 1 && nullableTransformFlags[0]) + if (((PEModuleSymbol)this.ContainingModule).Module.HasNullableAttribute(_handle, out byte transformFlag, out _)) { - return true; - } - - if (NonNullTypes == true) - { - return false; + switch ((NullableAnnotation)transformFlag) + { + case NullableAnnotation.Nullable: + return true; + case NullableAnnotation.NotNullable: + return false; + } } return null; diff --git a/src/Compilers/CSharp/Portable/Symbols/MethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/MethodSymbol.cs index 508f9b6a77793..30f985d341ed9 100644 --- a/src/Compilers/CSharp/Portable/Symbols/MethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/MethodSymbol.cs @@ -1174,7 +1174,7 @@ internal virtual void AddSynthesizedReturnTypeAttributes(PEModuleBuilder moduleB AddSynthesizedAttribute(ref attributes, compilation.SynthesizeTupleNamesAttribute(type.TypeSymbol)); } - if (type.ContainsNullableReferenceTypes()) + if (type.NeedsNullableAttribute()) { AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeNullableAttribute(this, type)); } diff --git a/src/Compilers/CSharp/Portable/Symbols/NamedTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/NamedTypeSymbol.cs index db8d6cb9f5375..5ac9afc8057ed 100644 --- a/src/Compilers/CSharp/Portable/Symbols/NamedTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/NamedTypeSymbol.cs @@ -758,7 +758,7 @@ private bool EqualsComplicatedCases(NamedTypeSymbol other, TypeCompareKind compa return true; } - internal override void AddNullableTransforms(ArrayBuilder transforms) + internal override void AddNullableTransforms(ArrayBuilder transforms) { ContainingType?.AddNullableTransforms(transforms); @@ -768,7 +768,7 @@ internal override void AddNullableTransforms(ArrayBuilder transforms) } } - internal override bool ApplyNullableTransforms(ImmutableArray transforms, INonNullTypesContext nonNullTypesContext, ref int position, out TypeSymbol result) + internal override bool ApplyNullableTransforms(byte defaultTransformFlag, ImmutableArray transforms, ref int position, out TypeSymbol result) { if (!IsGenericType) { @@ -784,7 +784,7 @@ internal override bool ApplyNullableTransforms(ImmutableArray transforms, { TypeSymbolWithAnnotations oldTypeArgument = allTypeArguments[i]; TypeSymbolWithAnnotations newTypeArgument; - if (!oldTypeArgument.ApplyNullableTransforms(transforms, nonNullTypesContext, ref position, out newTypeArgument)) + if (!oldTypeArgument.ApplyNullableTransforms(defaultTransformFlag, transforms, ref position, out newTypeArgument)) { allTypeArguments.Free(); result = this; diff --git a/src/Compilers/CSharp/Portable/Symbols/NamespaceSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/NamespaceSymbol.cs index 11dba599e9705..dfda7bf961895 100644 --- a/src/Compilers/CSharp/Portable/Symbols/NamespaceSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/NamespaceSymbol.cs @@ -119,7 +119,7 @@ public sealed override SymbolKind Kind } } - public override bool IsImplicitlyDeclared + public override sealed bool IsImplicitlyDeclared { get { diff --git a/src/Compilers/CSharp/Portable/Symbols/PointerTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/PointerTypeSymbol.cs index cabc47f1402da..313d423e69a1e 100644 --- a/src/Compilers/CSharp/Portable/Symbols/PointerTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/PointerTypeSymbol.cs @@ -249,17 +249,17 @@ private bool Equals(PointerTypeSymbol other, TypeCompareKind comparison) return true; } - internal override void AddNullableTransforms(ArrayBuilder transforms) + internal override void AddNullableTransforms(ArrayBuilder transforms) { PointedAtType.AddNullableTransforms(transforms); } - internal override bool ApplyNullableTransforms(ImmutableArray transforms, INonNullTypesContext nonNullTypesContext, ref int position, out TypeSymbol result) + internal override bool ApplyNullableTransforms(byte defaultTransformFlag, ImmutableArray transforms, ref int position, out TypeSymbol result) { TypeSymbolWithAnnotations oldPointedAtType = PointedAtType; TypeSymbolWithAnnotations newPointedAtType; - if (!oldPointedAtType.ApplyNullableTransforms(transforms, nonNullTypesContext, ref position, out newPointedAtType)) + if (!oldPointedAtType.ApplyNullableTransforms(defaultTransformFlag, transforms, ref position, out newPointedAtType)) { result = this; return false; diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/CustomModifierUtils.cs b/src/Compilers/CSharp/Portable/Symbols/Source/CustomModifierUtils.cs index 5658a163d6df3..9f54a1239934d 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/CustomModifierUtils.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/CustomModifierUtils.cs @@ -53,7 +53,7 @@ internal static void CopyMethodCustomModifiers( TypeSymbol returnTypeWithCustomModifiers = sourceMethodReturnType.TypeSymbol; if (returnTypeSymbol.Equals(returnTypeWithCustomModifiers, TypeCompareKind.AllIgnoreOptions)) { - returnType = returnType.WithTypeAndModifiers(CopyTypeCustomModifiers(returnTypeWithCustomModifiers, returnTypeSymbol, destinationMethod.ContainingAssembly, nonNullTypesContext: destinationMethod), + returnType = returnType.WithTypeAndModifiers(CopyTypeCustomModifiers(returnTypeWithCustomModifiers, returnTypeSymbol, destinationMethod.ContainingAssembly), sourceMethodReturnType.CustomModifiers); } } @@ -61,12 +61,10 @@ internal static void CopyMethodCustomModifiers( /// Type that already has custom modifiers. /// Same as , but without custom modifiers. May differ in object/dynamic. /// The assembly containing the signature referring to the destination type. - /// The NonNullTypes context at the destination. /// with custom modifiers copied from . - internal static TypeSymbol CopyTypeCustomModifiers(TypeSymbol sourceType, TypeSymbol destinationType, AssemblySymbol containingAssembly, INonNullTypesContext nonNullTypesContext) + internal static TypeSymbol CopyTypeCustomModifiers(TypeSymbol sourceType, TypeSymbol destinationType, AssemblySymbol containingAssembly) { Debug.Assert(sourceType.Equals(destinationType, TypeCompareKind.AllIgnoreOptions)); - Debug.Assert(nonNullTypesContext != null); const RefKind refKind = RefKind.None; @@ -94,11 +92,11 @@ internal static TypeSymbol CopyTypeCustomModifiers(TypeSymbol sourceType, TypeSy // If the destination had some of those annotations but not all, then clearly the destination // was incorrect. Or if the destination is C#7, then the destination will advertise annotations // that the author did not write and did not validate. - var flagsBuilder = ArrayBuilder.GetInstance(); + var flagsBuilder = ArrayBuilder.GetInstance(); destinationType.AddNullableTransforms(flagsBuilder); int position = 0; int length = flagsBuilder.Count; - bool transformResult = resultType.ApplyNullableTransforms(flagsBuilder.ToImmutableAndFree(), nonNullTypesContext, ref position, out resultType); + bool transformResult = resultType.ApplyNullableTransforms(defaultTransformFlag: 0, flagsBuilder.ToImmutableAndFree(), ref position, out resultType); Debug.Assert(transformResult && position == length); Debug.Assert(resultType.Equals(sourceType, TypeCompareKind.IgnoreDynamicAndTupleNames | TypeCompareKind.IgnoreNullableModifiersForReferenceTypes)); // Same custom modifiers as source type. diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/FieldSymbolWithAttributesAndModifiers.cs b/src/Compilers/CSharp/Portable/Symbols/Source/FieldSymbolWithAttributesAndModifiers.cs index b7b5420157e53..c6d202c9a7237 100755 --- a/src/Compilers/CSharp/Portable/Symbols/Source/FieldSymbolWithAttributesAndModifiers.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/FieldSymbolWithAttributesAndModifiers.cs @@ -233,11 +233,6 @@ internal override void DecodeWellKnownAttribute(ref DecodeWellKnownAttributeArgu // NullableAttribute should not be set explicitly. arguments.Diagnostics.Add(ErrorCode.ERR_ExplicitNullableAttribute, arguments.AttributeSyntaxOpt.Location); } - else if (attribute.IsTargetAttribute(this, AttributeDescription.NonNullTypesAttribute)) - { - // NonNullTypesAttribute should not be set explicitly. - arguments.Diagnostics.Add(ErrorCode.ERR_ExplicitNonNullTypesAttribute, arguments.AttributeSyntaxOpt.Location); - } } /// @@ -394,9 +389,7 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r DeclaringCompilation.SynthesizeTupleNamesAttribute(type.TypeSymbol)); } - AddSynthesizedNonNullTypesAttributeForMember(ref attributes); - - if (type.ContainsNullableReferenceTypes()) + if (type.NeedsNullableAttribute()) { AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeNullableAttribute(this, type)); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/LocalFunctionSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/LocalFunctionSymbol.cs index 438c6a47fbf64..c0f312c1decb9 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/LocalFunctionSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/LocalFunctionSymbol.cs @@ -235,7 +235,7 @@ internal void ComputeReturnType() DeclaringCompilation.EnsureIsReadOnlyAttributeExists(diagnostics, location, modifyCompilation: false); } - if (returnType.ContainsNullableReferenceTypes()) + if (returnType.NeedsNullableAttribute()) { DeclaringCompilation.EnsureNullableAttributeExists(diagnostics, location, 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 diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs b/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs index 96df6d00dfde5..fe7bf2bad5576 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs @@ -135,7 +135,7 @@ internal static void EnsureNullableAttributeExists(ImmutableArray attributes) @@ -325,9 +320,7 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r DeclaringCompilation.SynthesizeTupleNamesAttribute(type.TypeSymbol)); } - AddSynthesizedNonNullTypesAttributeForMember(ref attributes); - - if (type.ContainsNullableReferenceTypes()) + if (type.NeedsNullableAttribute()) { AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeNullableAttribute(this, type)); } @@ -558,10 +551,9 @@ protected void CheckModifiersAndType(DiagnosticBag diagnostics) return SourceDocumentationCommentUtils.GetAndCacheDocumentationComment(this, expandIncludes, ref _lazyDocComment); } - protected static void CopyEventCustomModifiers(EventSymbol eventWithCustomModifiers, ref TypeSymbolWithAnnotations type, AssemblySymbol containingAssembly, Symbol nonNullTypesContext) + protected static void CopyEventCustomModifiers(EventSymbol eventWithCustomModifiers, ref TypeSymbolWithAnnotations type, AssemblySymbol containingAssembly) { Debug.Assert((object)eventWithCustomModifiers != null); - Debug.Assert(nonNullTypesContext != null); TypeSymbol overriddenEventType = eventWithCustomModifiers.Type.TypeSymbol; @@ -570,7 +562,7 @@ protected static void CopyEventCustomModifiers(EventSymbol eventWithCustomModifi // we want to retain the original (incorrect) type to avoid hiding the type given in source. if (type.TypeSymbol.Equals(overriddenEventType, TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds | TypeCompareKind.IgnoreNullableModifiersForReferenceTypes | TypeCompareKind.IgnoreDynamic)) { - type = type.WithTypeAndModifiers(CustomModifierUtils.CopyTypeCustomModifiers(overriddenEventType, type.TypeSymbol, containingAssembly, nonNullTypesContext), + type = type.WithTypeAndModifiers(CustomModifierUtils.CopyTypeCustomModifiers(overriddenEventType, type.TypeSymbol, containingAssembly), eventWithCustomModifiers.Type.CustomModifiers); } } @@ -688,7 +680,7 @@ internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, this.CheckModifiersAndType(diagnostics); this.Type.CheckAllConstraints(conversions, location, diagnostics); - if (this.Type.ContainsNullableReferenceTypes()) + if (this.Type.NeedsNullableAttribute()) { this.DeclaringCompilation.EnsureNullableAttributeExists(diagnostics, location, modifyCompilation: true); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldLikeEventSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldLikeEventSymbol.cs index 9e0a3958085a4..de90ba74b008f 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldLikeEventSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldLikeEventSymbol.cs @@ -51,7 +51,7 @@ internal SourceFieldLikeEventSymbol(SourceMemberContainerTypeSymbol containingTy EventSymbol overriddenEvent = this.OverriddenEvent; if ((object)overriddenEvent != null) { - CopyEventCustomModifiers(overriddenEvent, ref _type, ContainingAssembly, nonNullTypesContext: this); + CopyEventCustomModifiers(overriddenEvent, ref _type, ContainingAssembly); } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldSymbol.cs index 7e13447629903..663d0bf8f0648 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldSymbol.cs @@ -128,7 +128,7 @@ internal sealed override void DecodeWellKnownAttribute(ref DecodeWellKnownAttrib internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, DiagnosticBag diagnostics) { var location = ErrorLocation; - if (this.Type.ContainsNullableReferenceTypes()) + if (this.Type.NeedsNullableAttribute()) { DeclaringCompilation.EnsureNullableAttributeExists(diagnostics, location, modifyCompilation: true); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs index 4a6edd640d076..f753b59a5c3b0 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs @@ -1417,8 +1417,8 @@ protected void AfterMembersChecks(DiagnosticBag diagnostics) // https://github.com/dotnet/roslyn/issues/30080: Report diagnostics for base type and interfaces at more specific locations. var baseType = BaseTypeNoUseSiteDiagnostics; var interfaces = InterfacesNoUseSiteDiagnostics(); - if (baseType?.ContainsNullableReferenceTypes() == true || - interfaces.Any(t => t.ContainsNullableReferenceTypes())) + if (baseType?.NeedsNullableAttribute() == true || + interfaces.Any(t => t.NeedsNullableAttribute())) { this.DeclaringCompilation.EnsureNullableAttributeExists(diagnostics, location, modifyCompilation: true); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs index 7a5e4ea26f3b5..e0ddab2886172 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs @@ -1206,11 +1206,6 @@ private void DecodeWellKnownAttributeAppliedToMethod(ref DecodeWellKnownAttribut arguments.Diagnostics.Add(ErrorCode.ERR_SecurityCriticalOrSecuritySafeCriticalOnAsync, arguments.AttributeSyntaxOpt.Location, arguments.AttributeSyntaxOpt.GetErrorDisplayName()); } } - else if (attribute.IsTargetAttribute(this, AttributeDescription.NonNullTypesAttribute)) - { - // NonNullTypesAttribute should not be set explicitly. - arguments.Diagnostics.Add(ErrorCode.ERR_ExplicitNonNullTypesAttribute, arguments.AttributeSyntaxOpt.Location); - } else { var compilation = this.DeclaringCompilation; @@ -1623,8 +1618,6 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); - AddSynthesizedNonNullTypesAttributeForMember(ref attributes); - bool isAsync = this.IsAsync; bool isIterator = this.IsIterator; diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceModuleSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceModuleSymbol.cs index d2bcfa0424aaf..4168ec02aa9a6 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceModuleSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceModuleSymbol.cs @@ -511,11 +511,6 @@ internal override void DecodeWellKnownAttribute(ref DecodeWellKnownAttributeArgu arguments.GetOrCreateData().DefaultCharacterSet = charSet; } } - else if (attribute.IsTargetAttribute(this, AttributeDescription.NonNullTypesAttribute)) - { - // NonNullTypesAttribute should not be set explicitly. - arguments.Diagnostics.Add(ErrorCode.ERR_ExplicitNonNullTypesAttribute, arguments.AttributeSyntaxOpt.Location); - } } public override bool? NonNullTypes @@ -540,13 +535,6 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r WellKnownMember.System_Security_UnverifiableCodeAttribute__ctor)); } } - - bool? nonNullTypes = NonNullTypes; - if (nonNullTypes != null) - { - AddSynthesizedAttribute(ref attributes, - compilation.TrySynthesizeNonNullTypesAttribute(nonNullTypes.GetValueOrDefault())); - } } internal override bool HasAssemblyCompilationRelaxationsAttribute diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs index a7b81143b23cd..8a7a41cc24135 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs @@ -748,11 +748,6 @@ internal sealed override void DecodeWellKnownAttribute(ref DecodeWellKnownAttrib // NullableAttribute should not be set explicitly. arguments.Diagnostics.Add(ErrorCode.ERR_ExplicitNullableAttribute, arguments.AttributeSyntaxOpt.Location); } - else if (attribute.IsTargetAttribute(this, AttributeDescription.NonNullTypesAttribute)) - { - // NonNullTypesAttribute should not be set explicitly. - arguments.Diagnostics.Add(ErrorCode.ERR_ExplicitNonNullTypesAttribute, arguments.AttributeSyntaxOpt.Location); - } else { var compilation = this.DeclaringCompilation; @@ -1224,18 +1219,11 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r AddSynthesizedAttribute(ref attributes, compilation.SynthesizeTupleNamesAttribute(baseType)); } - if (baseType.ContainsNullableReferenceTypes()) + if (baseType.NeedsNullableAttribute()) { AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeNullableAttribute(this, TypeSymbolWithAnnotations.Create(baseType))); } } - - bool? nonNullTypes = NonNullTypes; - if (nonNullTypes.HasValue && nonNullTypes != ((Symbol)ContainingType ?? ContainingModule).NonNullTypes) - { - AddSynthesizedAttribute(ref attributes, - compilation.TrySynthesizeNonNullTypesAttribute(nonNullTypes.GetValueOrDefault())); - } } #endregion diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamespaceSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamespaceSymbol.cs index 06d7bc04171f9..46c490ff3548e 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamespaceSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamespaceSymbol.cs @@ -296,7 +296,7 @@ private Dictionary> MakeNameToMemb { builder.Add(BuildSymbol(declaration, diagnostics)); } - builder.AddInjectedSymbols(containingNamespace: this); + var result = builder.CreateMap(); CheckMembers(this, result, diagnostics); @@ -534,190 +534,6 @@ public Dictionary> CreateMap() return result; } - - public void AddInjectedSymbols(NamespaceSymbol containingNamespace) - { - if (containingNamespace.DeclaringCompilation.Options.OutputKind.IsNetModule()) - { - return; - } - - const string codeAnalysis = "CodeAnalysis"; - const string system = "System"; - const string microsoft = "Microsoft"; - const string runtime = "Runtime"; - const string compilerServices = "CompilerServices"; - - if (containingNamespace.IsGlobalNamespace) - { - if (!_dictionary.ContainsKey(system)) - { - Add(makeEmptyNamespace(system)); - } - if (!_dictionary.ContainsKey(microsoft)) - { - Add(makeEmptyNamespace(microsoft)); - } - return; - } - - switch (containingNamespace.Name) - { - case system: - if (containingNamespace.ContainingNamespace.IsGlobalNamespace && !_dictionary.ContainsKey(runtime)) - { - Add(makeEmptyNamespace(runtime)); - } - return; - case runtime: - if (isSystem(containingNamespace.ContainingNamespace) && !_dictionary.ContainsKey(compilerServices)) - { - Add(makeEmptyNamespace(compilerServices)); - } - return; - case microsoft: - if (containingNamespace.ContainingNamespace.IsGlobalNamespace && !_dictionary.ContainsKey(codeAnalysis)) - { - Add(makeEmptyNamespace(codeAnalysis)); - } - return; - case compilerServices: - if (isRuntime(containingNamespace.ContainingNamespace) && !_dictionary.ContainsKey("NonNullTypesAttribute")) - { - Add(InjectedNonNullTypesAttributeSymbol.Create(containingNamespace)); - } - return; - case codeAnalysis: - if (isMicrosoft(containingNamespace.ContainingNamespace) && !_dictionary.ContainsKey("EmbeddedAttribute")) - { - Add(InjectedEmbeddedAttributeSymbol.Create(containingNamespace)); - } - return; - } - - InjectedNamespaceSymbol makeEmptyNamespace(string name) - { - return new InjectedNamespaceSymbol(containingNamespace, name); - } - - bool isSystem(NamespaceSymbol symbol) - { - return symbol.Name == system && symbol.ContainingNamespace.IsGlobalNamespace; - } - - bool isRuntime(NamespaceSymbol symbol) - { - return symbol.Name == runtime && isSystem(symbol.ContainingNamespace); - } - - bool isMicrosoft(NamespaceSymbol symbol) - { - return symbol.Name == microsoft && symbol.ContainingNamespace.IsGlobalNamespace; - } - } - - class InjectedNamespaceSymbol : NamespaceSymbol - { - private readonly NamespaceSymbol _containingNamespace; - private readonly string _name; - private Dictionary> _nameToMembersMap; - private Dictionary> _nameToTypeMembersMap; - private ImmutableArray _lazyAllMembersOrdered; - private ImmutableArray _lazyTypeMembersOrdered; - - public InjectedNamespaceSymbol(NamespaceSymbol containingNamespace, string name) - { - Debug.Assert(name != null); - _containingNamespace = containingNamespace; - _name = name; - } - - public override string Name - => _name; - - public override AssemblySymbol ContainingAssembly - => _containingNamespace.ContainingAssembly; - - public override Symbol ContainingSymbol - => _containingNamespace; - - public override ImmutableArray Locations - => ImmutableArray.Empty; - - public override ImmutableArray DeclaringSyntaxReferences - => ImmutableArray.Empty; - - internal override NamespaceExtent Extent - => _containingNamespace.Extent; - - public override ImmutableArray GetMembers() - { - if (_lazyAllMembersOrdered == null) - { - var members = StaticCast.From(this.GetNameToMembersMap().Flatten(null).Sort(LexicalOrderSymbolComparer.Instance)); - ImmutableInterlocked.InterlockedInitialize(ref _lazyAllMembersOrdered, members); - } - return _lazyAllMembersOrdered; - } - - public override ImmutableArray GetMembers(string name) - { - ImmutableArray members; - return this.GetNameToMembersMap().TryGetValue(name, out members) - ? members.Cast() - : ImmutableArray.Empty; - } - - private Dictionary> GetNameToMembersMap() - { - if (_nameToMembersMap == null) - { - var builder = new NameToSymbolMapBuilder(1); - builder.AddInjectedSymbols(containingNamespace: this); - var map = builder.CreateMap(); - - var diagnostics = DiagnosticBag.GetInstance(); - CheckMembers(this, map, diagnostics); - this.DeclaringCompilation.DeclarationDiagnostics.AddRange(diagnostics); - diagnostics.Free(); - - Interlocked.CompareExchange(ref _nameToMembersMap, map, null); - } - - return _nameToMembersMap; - } - - private Dictionary> GetNameToTypeMembersMap() - { - if (_nameToTypeMembersMap == null) - { - Interlocked.CompareExchange(ref _nameToTypeMembersMap, GetTypesFromMemberMap(GetNameToMembersMap()), null); - } - - return _nameToTypeMembersMap; - } - - public override ImmutableArray GetTypeMembers() - { - if (_lazyTypeMembersOrdered.IsDefault) - { - var members = this.GetNameToTypeMembersMap().Flatten(LexicalOrderSymbolComparer.Instance); - ImmutableInterlocked.InterlockedInitialize(ref _lazyTypeMembersOrdered, members); - } - - return _lazyTypeMembersOrdered; - } - - public override ImmutableArray GetTypeMembers(string name) - { - ImmutableArray members; - return this.GetNameToTypeMembersMap().TryGetValue(name, out members) - ? members - : ImmutableArray.Empty; - } - - public override bool IsImplicitlyDeclared => true; - } } } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodSymbol.cs index e3df2b1ca91c7..8e4451ba65707 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodSymbol.cs @@ -1044,7 +1044,7 @@ internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, ParameterHelpers.EnsureIsReadOnlyAttributeExists(Parameters, diagnostics, modifyCompilation: true); - if (ReturnType.ContainsNullableReferenceTypes()) + if (ReturnType.NeedsNullableAttribute()) { this.DeclaringCompilation.EnsureNullableAttributeExists(diagnostics, location, modifyCompilation: true); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceParameterSymbol.cs index d0a737994dab6..18486860f8eef 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceParameterSymbol.cs @@ -116,7 +116,7 @@ internal override ParameterSymbol WithCustomModifiersAndParams(TypeSymbol newTyp internal SourceParameterSymbol WithCustomModifiersAndParamsCore(TypeSymbol newType, ImmutableArray newCustomModifiers, ImmutableArray newRefCustomModifiers, bool newIsParams) { - newType = CustomModifierUtils.CopyTypeCustomModifiers(newType, this.Type.TypeSymbol, this.ContainingAssembly, nonNullTypesContext: this); + newType = CustomModifierUtils.CopyTypeCustomModifiers(newType, this.Type.TypeSymbol, this.ContainingAssembly); TypeSymbolWithAnnotations newTypeWithModifiers = this.Type.WithTypeAndModifiers(newType, newCustomModifiers); diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceParameterSymbolBase.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceParameterSymbolBase.cs index c73267474b5da..d87804cf50ca4 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceParameterSymbolBase.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceParameterSymbolBase.cs @@ -96,7 +96,7 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeIsReadOnlyAttribute(this)); } - if (type.ContainsNullableReferenceTypes()) + if (type.NeedsNullableAttribute()) { AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeNullableAttribute(this, type)); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertyAccessorSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertyAccessorSymbol.cs index e7c5832e502ba..a9d49a2e685b0 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertyAccessorSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertyAccessorSymbol.cs @@ -289,7 +289,7 @@ protected override void MethodChecks(DiagnosticBag diagnostics) PropertySymbol associatedProperty = _property; var type = associatedProperty.Type; _lazyReturnType = _lazyReturnType.WithTypeAndModifiers( - CustomModifierUtils.CopyTypeCustomModifiers(type.TypeSymbol, _lazyReturnType.TypeSymbol, this.ContainingAssembly, nonNullTypesContext: associatedProperty), + CustomModifierUtils.CopyTypeCustomModifiers(type.TypeSymbol, _lazyReturnType.TypeSymbol, this.ContainingAssembly), type.CustomModifiers); _lazyRefCustomModifiers = associatedProperty.RefCustomModifiers; } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbol.cs index 6548d3f21cfa0..a41eb0f770eff 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbol.cs @@ -274,7 +274,7 @@ private SourcePropertySymbol( if (type.TypeSymbol.Equals(overriddenPropertyType.TypeSymbol, TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds | TypeCompareKind.IgnoreNullableModifiersForReferenceTypes | TypeCompareKind.IgnoreDynamic)) { type = type.WithTypeAndModifiers( - CustomModifierUtils.CopyTypeCustomModifiers(overriddenPropertyType.TypeSymbol, type.TypeSymbol, this.ContainingAssembly, nonNullTypesContext: this), + CustomModifierUtils.CopyTypeCustomModifiers(overriddenPropertyType.TypeSymbol, type.TypeSymbol, this.ContainingAssembly), overriddenPropertyType.CustomModifiers); _lazyType = default; _lazyType.InterlockedInitialize(type); @@ -769,7 +769,7 @@ internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, ParameterHelpers.EnsureIsReadOnlyAttributeExists(Parameters, diagnostics, modifyCompilation: true); - if (this.Type.ContainsNullableReferenceTypes()) + if (this.Type.NeedsNullableAttribute()) { DeclaringCompilation.EnsureNullableAttributeExists(diagnostics, location, modifyCompilation: true); } @@ -1178,9 +1178,7 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r DeclaringCompilation.SynthesizeTupleNamesAttribute(type.TypeSymbol)); } - AddSynthesizedNonNullTypesAttributeForMember(ref attributes); - - if (type.ContainsNullableReferenceTypes()) + if (type.NeedsNullableAttribute()) { AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeNullableAttribute(this, type)); } @@ -1315,11 +1313,6 @@ internal override void DecodeWellKnownAttribute(ref DecodeWellKnownAttributeArgu // NullableAttribute should not be set explicitly. arguments.Diagnostics.Add(ErrorCode.ERR_ExplicitNullableAttribute, arguments.AttributeSyntaxOpt.Location); } - else if (attribute.IsTargetAttribute(this, AttributeDescription.NonNullTypesAttribute)) - { - // NonNullTypesAttribute should not be set explicitly. - arguments.Diagnostics.Add(ErrorCode.ERR_ExplicitNonNullTypesAttribute, arguments.AttributeSyntaxOpt.Location); - } } internal override void PostDecodeWellKnownAttributes(ImmutableArray boundAttributes, ImmutableArray allAttributeSyntaxNodes, DiagnosticBag diagnostics, AttributeLocation symbolPart, WellKnownAttributeData decodedData) diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceTypeParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceTypeParameterSymbol.cs index aff2acf7a46ed..f791484f996a4 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceTypeParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceTypeParameterSymbol.cs @@ -305,8 +305,8 @@ private bool ModifyCompilationForAttributeEmbedding() private void CheckNullableAnnotationsInConstraints(DiagnosticBag diagnostics) { - if (this.ReferenceTypeConstraintIsNullable == true || - this.ConstraintTypesNoUseSiteDiagnostics.Any(c => c.ContainsNullableReferenceTypes())) + if ((this.HasReferenceTypeConstraint && this.ReferenceTypeConstraintIsNullable != null) || + this.ConstraintTypesNoUseSiteDiagnostics.Any(c => c.NeedsNullableAttribute())) { DeclaringCompilation.EnsureNullableAttributeExists(diagnostics, this.GetNonNullSyntaxNode().Location, ModifyCompilationForAttributeEmbedding()); } @@ -361,11 +361,18 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeIsUnmanagedAttribute(this)); } - if (this.ReferenceTypeConstraintIsNullable == true) + if (this.HasReferenceTypeConstraint && this.ReferenceTypeConstraintIsNullable != null) { + NamedTypeSymbol byteType = DeclaringCompilation.GetSpecialType(SpecialType.System_Byte); + Debug.Assert((object)byteType != null); + AddSynthesizedAttribute( ref attributes, - moduleBuilder.SynthesizeNullableAttribute(WellKnownMember.System_Runtime_CompilerServices_NullableAttribute__ctor, ImmutableArray.Empty)); + moduleBuilder.SynthesizeNullableAttribute(WellKnownMember.System_Runtime_CompilerServices_NullableAttribute__ctorByte, + ImmutableArray.Create(new TypedConstant(byteType, TypedConstantKind.Primitive, + (byte)(this.ReferenceTypeConstraintIsNullable == true ? + NullableAnnotation.Nullable : + NullableAnnotation.NotNullable))))); } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceUserDefinedOperatorSymbolBase.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceUserDefinedOperatorSymbolBase.cs index 25d5d69be297c..55e93abc9aca6 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceUserDefinedOperatorSymbolBase.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceUserDefinedOperatorSymbolBase.cs @@ -654,7 +654,7 @@ internal sealed override void AfterAddingTypeMembersChecks(ConversionsBase conve ParameterHelpers.EnsureIsReadOnlyAttributeExists(Parameters, diagnostics, modifyCompilation: true); var location = ReturnTypeSyntax.Location; - if (ReturnType.ContainsNullableReferenceTypes()) + if (ReturnType.NeedsNullableAttribute()) { this.DeclaringCompilation.EnsureNullableAttributeExists(diagnostics, location, modifyCompilation: true); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Symbol.cs b/src/Compilers/CSharp/Portable/Symbols/Symbol.cs index 045e9635e6074..86633e660bc90 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Symbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Symbol.cs @@ -631,16 +631,6 @@ internal virtual void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, re { } - protected void AddSynthesizedNonNullTypesAttributeForMember(ref ArrayBuilder attributes) - { - bool? nonNullTypes = NonNullTypes; - if (nonNullTypes.HasValue && nonNullTypes != ContainingType.NonNullTypes) - { - AddSynthesizedAttribute(ref attributes, - DeclaringCompilation.TrySynthesizeNonNullTypesAttribute(nonNullTypes.GetValueOrDefault())); - } - } - /// /// Convenience helper called by subclasses to add a synthesized attribute to a collection of attributes. /// diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/InjectedAttributeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/InjectedAttributeSymbol.cs deleted file mode 100644 index 91d996f9c5bbf..0000000000000 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/InjectedAttributeSymbol.cs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Immutable; - -namespace Microsoft.CodeAnalysis.CSharp.Symbols -{ - /// - /// Injected attribute symbols are injected early in the compilation, and so can be referenced in source. - /// But we track their usage and only emit them if they are used. - /// Their method bodies are always compiled, in case we do need to emit them. - /// - internal abstract class InjectedAttributeSymbol : SynthesizedEmbeddedAttributeSymbol - { - internal abstract void AddDiagnostics(DiagnosticBag recipient); - - // All the diagnostics involved in constructing this symbol will only be produced - // if the symbol is referenced and so ends up emitted. - // We collect all those diagnostics here. - protected readonly DiagnosticBag _diagnostics; - - public InjectedAttributeSymbol( - AttributeDescription description, - NamespaceSymbol containingNamespace, - CSharpCompilation compilation, - Func> getConstructors) - : this(description, containingNamespace, compilation, getConstructors, new DiagnosticBag()) - { - } - - private InjectedAttributeSymbol( - AttributeDescription description, - NamespaceSymbol containingNamespace, - CSharpCompilation compilation, - Func> getConstructors, - DiagnosticBag diagnostics) - : base(description, containingNamespace, compilation, getConstructors, diagnostics) - { - _diagnostics = diagnostics; - } - } -} diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/InjectedEmbeddedAttributeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/InjectedEmbeddedAttributeSymbol.cs deleted file mode 100644 index cb93f6014b241..0000000000000 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/InjectedEmbeddedAttributeSymbol.cs +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Immutable; -using System.Diagnostics; - -namespace Microsoft.CodeAnalysis.CSharp.Symbols -{ - /// - /// Makes the Microsoft.CodeAnalysis.EmbeddedAttribute available in every compilation. - /// - internal sealed class InjectedEmbeddedAttributeSymbol : InjectedAttributeSymbol - { - private InjectedEmbeddedAttributeSymbol( - AttributeDescription description, - NamespaceSymbol containingNamespace, - CSharpCompilation compilation, - Func> getConstructors) - : base(description, containingNamespace, compilation, getConstructors) - { - } - - public static InjectedEmbeddedAttributeSymbol Create(NamespaceSymbol containingNamespace) - { - return new InjectedEmbeddedAttributeSymbol(AttributeDescription.CodeAnalysisEmbeddedAttribute, containingNamespace, containingNamespace.DeclaringCompilation, makeConstructor); - - ImmutableArray makeConstructor(CSharpCompilation compilation, NamedTypeSymbol containingType, DiagnosticBag diagnostics) - { - return ImmutableArray.Create(new EmbeddedAttributeConstructorSymbol(containingType)); - } - } - - internal override AttributeUsageInfo GetAttributeUsageInfo() - => new AttributeUsageInfo(validTargets: AttributeTargets.All, allowMultiple: false, inherited: false); - - internal override void AddDiagnostics(DiagnosticBag recipient) - => recipient.AddRange(_diagnostics); - - private sealed class EmbeddedAttributeConstructorSymbol : SynthesizedInstanceConstructor - { - internal EmbeddedAttributeConstructorSymbol(NamedTypeSymbol containingType) - : base(containingType) - { - Debug.Assert(containingType is InjectedEmbeddedAttributeSymbol); - } - - public override ImmutableArray Parameters - => ImmutableArray.Empty; - - internal override bool SynthesizesLoweredBoundBody - => true; - - /// - /// Note: this method captures diagnostics into the containing type (an injected attribute symbol) instead, - /// as we don't yet know if the containing type will be emitted. - /// - internal override void GenerateMethodBody(TypeCompilationState compilationState, DiagnosticBag diagnostics) - { - var containingType = (InjectedEmbeddedAttributeSymbol)ContainingType; - GenerateMethodBodyCore(compilationState, containingType._diagnostics); - } - } - } -} diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/InjectedNonNullTypesAttributeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/InjectedNonNullTypesAttributeSymbol.cs deleted file mode 100644 index 33f94ddd2887b..0000000000000 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/InjectedNonNullTypesAttributeSymbol.cs +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Diagnostics; - -namespace Microsoft.CodeAnalysis.CSharp.Symbols -{ - /// - /// Makes the System.Runtime.CompilerServices.NonNullTypesAttribute available in every compilation. - /// - internal sealed class InjectedNonNullTypesAttributeSymbol : InjectedAttributeSymbol - { - private ImmutableArray _lazyCustomAttributes; - - private InjectedNonNullTypesAttributeSymbol( - AttributeDescription description, - NamespaceSymbol containingNamespace, - CSharpCompilation compilation, - Func> getConstructors) - : base(description, containingNamespace, compilation, getConstructors) - { - } - - public static InjectedNonNullTypesAttributeSymbol Create(NamespaceSymbol containingNamespace) - { - return new InjectedNonNullTypesAttributeSymbol(AttributeDescription.NonNullTypesAttribute, containingNamespace, containingNamespace.DeclaringCompilation, makeConstructor); - - ImmutableArray makeConstructor(CSharpCompilation compilation, NamedTypeSymbol containingType, DiagnosticBag diagnostics) - { - var boolType = compilation.GetSpecialType(SpecialType.System_Boolean); - - Binder.ReportUseSiteDiagnostics(boolType, diagnostics, Location.None); - - var boolWithAnnotations = TypeSymbolWithAnnotations.Create(boolType); - // https://github.com/dotnet/roslyn/issues/30143: Constructor should save the parameter into a field (for users of reflection) - return ImmutableArray.Create( - new NonNullTypesAttributeConstructorSymbol( - containingType, - m => ImmutableArray.Create(SynthesizedParameterSymbol.Create(m, boolWithAnnotations, 0, ConstantValue.True, name: "flag")))); - } - } - - internal override void AddDiagnostics(DiagnosticBag recipient) - { - // pull on the attributes to collect their diagnostics too - _ = GetAttributes(); - recipient.AddRange(_diagnostics); - } - - public override ImmutableArray GetAttributes() - { - if (_lazyCustomAttributes.IsDefault) - { - // https://github.com/dotnet/roslyn/issues/29732 A race condition can produce duplicate diagnostics here - ImmutableInterlocked.InterlockedInitialize(ref _lazyCustomAttributes, MakeAttributes()); - } - return _lazyCustomAttributes; - } - - /// - /// Adds an `[AttributeUsage(AttributeTargets.Class | ...)]` (if possible) and captures any diagnostics in the process. - /// - private ImmutableArray MakeAttributes() - { - var ctor = (MethodSymbol)Binder.GetWellKnownTypeMember(DeclaringCompilation, WellKnownMember.System_AttributeUsageAttribute__ctor, _diagnostics, Location.None); - if (ctor is null) - { - // member is missing - return ImmutableArray.Empty; - } - - NamedTypeSymbol attributeTargets = DeclaringCompilation.GetWellKnownType(WellKnownType.System_AttributeTargets); - Binder.ReportUseSiteDiagnostics(attributeTargets, _diagnostics, Location.None); - - var usage = new SynthesizedAttributeData(ctor, - arguments: ImmutableArray.Create(new TypedConstant(attributeTargets, TypedConstantKind.Enum, attributeUsage)), - namedArguments: ImmutableArray>.Empty); - - return ImmutableArray.Create(usage); - } - - internal override AttributeUsageInfo GetAttributeUsageInfo() - => new AttributeUsageInfo(validTargets: attributeUsage, allowMultiple: false, inherited: false); - - private const AttributeTargets attributeUsage = - AttributeTargets.Class | - AttributeTargets.Constructor | - AttributeTargets.Delegate | - AttributeTargets.Enum | - AttributeTargets.Event | - AttributeTargets.Field | - AttributeTargets.Interface | - AttributeTargets.Method | - AttributeTargets.Module | - AttributeTargets.Property | - AttributeTargets.Struct; - - private sealed class NonNullTypesAttributeConstructorSymbol : SynthesizedInstanceConstructor - { - private readonly ImmutableArray _parameters; - - internal NonNullTypesAttributeConstructorSymbol( - NamedTypeSymbol containingType, - Func> getParameters) : - base(containingType) - { - Debug.Assert(containingType is InjectedNonNullTypesAttributeSymbol); - _parameters = getParameters(this); - } - - public override ImmutableArray Parameters - => _parameters; - - internal override bool SynthesizesLoweredBoundBody - => true; - - /// - /// Note: this method captures diagnostics into the containing type (an injected attribute symbol) instead, - /// as we don't yet know if the containing type will be emitted. - /// - internal override void GenerateMethodBody(TypeCompilationState compilationState, DiagnosticBag diagnostics) - { - var containingType = (InjectedNonNullTypesAttributeSymbol)ContainingType; - GenerateMethodBodyCore(compilationState, containingType._diagnostics); - } - } - } -} diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEmbeddedAttributeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEmbeddedAttributeSymbol.cs index 45346ce40eac4..6e2c322e38d51 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEmbeddedAttributeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEmbeddedAttributeSymbol.cs @@ -33,19 +33,21 @@ internal class SynthesizedEmbeddedAttributeSymbol : NamedTypeSymbol public SynthesizedEmbeddedAttributeSymbol( AttributeDescription description, CSharpCompilation compilation, - Func> getAdditionalConstructors, + Func> getConstructors, DiagnosticBag diagnostics) { _name = description.Name; _baseType = MakeBaseType(compilation, diagnostics); - var builder = ArrayBuilder.GetInstance(); - builder.Add(new SynthesizedEmbeddedAttributeConstructorSymbol(this, m => ImmutableArray.Empty)); - if (getAdditionalConstructors != null) + if (getConstructors != null) + { + _constructors = getConstructors(compilation, this, diagnostics); + } + else { - builder.AddRange(getAdditionalConstructors(compilation, this, diagnostics)); + _constructors = ImmutableArray.Create(new SynthesizedEmbeddedAttributeConstructorSymbol(this, m => ImmutableArray.Empty)); } - _constructors = builder.ToImmutableAndFree(); + Debug.Assert(_constructors.Length == description.Signatures.Length); _module = compilation.SourceModule; @@ -190,12 +192,9 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r ref attributes, moduleBuilder.Compilation.TrySynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_CompilerGeneratedAttribute__ctor)); - if (!DeclaringCompilation.GetWellKnownType(WellKnownType.Microsoft_CodeAnalysis_EmbeddedAttribute).IsErrorType()) - { - AddSynthesizedAttribute( - ref attributes, - moduleBuilder.Compilation.TrySynthesizeAttribute(WellKnownMember.Microsoft_CodeAnalysis_EmbeddedAttribute__ctor)); - } + AddSynthesizedAttribute( + ref attributes, + moduleBuilder.SynthesizeEmbeddedAttribute()); } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedFieldSymbolBase.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedFieldSymbolBase.cs index 5f7864dd9c986..35a59448458de 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedFieldSymbolBase.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedFieldSymbolBase.cs @@ -67,7 +67,7 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r compilation.SynthesizeTupleNamesAttribute(Type.TypeSymbol)); } - if (Type.ContainsNullableReferenceTypes()) + if (Type.NeedsNullableAttribute()) { AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeNullableAttribute(this, this.Type)); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedInstanceConstructor.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedInstanceConstructor.cs index 3b70aad622de5..34dbac24f3345 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedInstanceConstructor.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedInstanceConstructor.cs @@ -147,7 +147,7 @@ public override RefKind RefKind public sealed override TypeSymbolWithAnnotations ReturnType { - get { return TypeSymbolWithAnnotations.Create(nonNullTypesContext: this, ContainingAssembly.GetSpecialType(SpecialType.System_Void)); } + get { return TypeSymbolWithAnnotations.Create(ContainingAssembly.GetSpecialType(SpecialType.System_Void)); } } public override ImmutableArray RefCustomModifiers diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedParameterSymbol.cs index b157d09485e2e..d1e5f33333b41 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedParameterSymbol.cs @@ -159,7 +159,7 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r compilation.SynthesizeTupleNamesAttribute(type.TypeSymbol)); } - if (Type.ContainsNullableReferenceTypes()) + if (Type.NeedsNullableAttribute()) { AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeNullableAttribute(this, Type)); } @@ -199,17 +199,6 @@ public static ParameterSymbol Create( return new SynthesizedParameterSymbolWithCustomModifiers(container, type, ordinal, refKind, name, refCustomModifiers); } - public static ParameterSymbol Create( - MethodSymbol container, - TypeSymbolWithAnnotations type, - int ordinal, - ConstantValue defaultValue, - string name = "") - { - Debug.Assert(defaultValue != null); - return new SynthesizedParameterSymbolWithDefaultValue(container, type, ordinal, defaultValue, name); - } - /// /// For each parameter of a source method, construct a corresponding synthesized parameter /// for a destination method. @@ -236,25 +225,6 @@ public override ImmutableArray RefCustomModifiers get { return ImmutableArray.Empty; } } - private sealed class SynthesizedParameterSymbolWithDefaultValue : SynthesizedParameterSymbolBase - { - private readonly ConstantValue _defaultValue; - public SynthesizedParameterSymbolWithDefaultValue(MethodSymbol container, TypeSymbolWithAnnotations type, int ordinal, ConstantValue defaultValue, string name) - : base(container, type, ordinal, RefKind.None, name) - { - Debug.Assert(!defaultValue.IsBad); - _defaultValue = defaultValue; - } - - internal override bool IsMetadataOptional => true; - internal override ConstantValue ExplicitDefaultConstantValue => _defaultValue; - - public override ImmutableArray RefCustomModifiers - { - get { return ImmutableArray.Empty; } - } - } - private sealed class SynthesizedParameterSymbolWithCustomModifiers : SynthesizedParameterSymbolBase { private readonly ImmutableArray _refCustomModifiers; diff --git a/src/Compilers/CSharp/Portable/Symbols/Tuples/TupleTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Tuples/TupleTypeSymbol.cs index 13feaadca1d23..4478e9e139eed 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Tuples/TupleTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Tuples/TupleTypeSymbol.cs @@ -1430,14 +1430,14 @@ internal override bool IsInterface } } - internal override void AddNullableTransforms(ArrayBuilder transforms) + internal override void AddNullableTransforms(ArrayBuilder transforms) { _underlyingType.AddNullableTransforms(transforms); } - internal override bool ApplyNullableTransforms(ImmutableArray transforms, INonNullTypesContext nonNullTypesContext, ref int position, out TypeSymbol result) + internal override bool ApplyNullableTransforms(byte defaultTransformFlag, ImmutableArray transforms, ref int position, out TypeSymbol result) { - if (_underlyingType.ApplyNullableTransforms(transforms, nonNullTypesContext, ref position, out TypeSymbol underlying)) + if (_underlyingType.ApplyNullableTransforms(defaultTransformFlag, transforms, ref position, out TypeSymbol underlying)) { result = this.WithUnderlyingType((NamedTypeSymbol)underlying); return true; diff --git a/src/Compilers/CSharp/Portable/Symbols/TypeParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/TypeParameterSymbol.cs index 51b361ae92a27..37f3c63106d0d 100644 --- a/src/Compilers/CSharp/Portable/Symbols/TypeParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/TypeParameterSymbol.cs @@ -667,11 +667,11 @@ public override int GetHashCode() return Hash.Combine(ContainingSymbol, Ordinal); } - internal override void AddNullableTransforms(ArrayBuilder transforms) + internal override void AddNullableTransforms(ArrayBuilder transforms) { } - internal override bool ApplyNullableTransforms(ImmutableArray transforms, INonNullTypesContext nonNullTypesContext, ref int position, out TypeSymbol result) + internal override bool ApplyNullableTransforms(byte defaultTransformFlag, ImmutableArray transforms, ref int position, out TypeSymbol result) { result = this; return true; diff --git a/src/Compilers/CSharp/Portable/Symbols/TypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/TypeSymbol.cs index 1777c2e77ae7b..eff1c95406703 100644 --- a/src/Compilers/CSharp/Portable/Symbols/TypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/TypeSymbol.cs @@ -624,14 +624,14 @@ public virtual NamedTypeSymbol TupleUnderlyingType /// internal abstract bool IsManagedType { get; } - internal bool ContainsNullableReferenceTypes() + internal bool NeedsNullableAttribute() { - return TypeSymbolWithAnnotations.ContainsNullableReferenceTypes(typeWithAnnotationsOpt: default, typeOpt: this); + return TypeSymbolWithAnnotations.NeedsNullableAttribute(typeWithAnnotationsOpt: default, typeOpt: this); } - internal abstract void AddNullableTransforms(ArrayBuilder transforms); + internal abstract void AddNullableTransforms(ArrayBuilder transforms); - internal abstract bool ApplyNullableTransforms(ImmutableArray transforms, INonNullTypesContext nonNullTypesContext, ref int position, out TypeSymbol result); + internal abstract bool ApplyNullableTransforms(byte defaultTransformFlag, ImmutableArray transforms, ref int position, out TypeSymbol result); internal abstract TypeSymbol SetUnknownNullabilityForReferenceTypes(); diff --git a/src/Compilers/CSharp/Portable/Symbols/TypeSymbolExtensions.cs b/src/Compilers/CSharp/Portable/Symbols/TypeSymbolExtensions.cs index 985f1980fa97f..93a843ed2c10b 100644 --- a/src/Compilers/CSharp/Portable/Symbols/TypeSymbolExtensions.cs +++ b/src/Compilers/CSharp/Portable/Symbols/TypeSymbolExtensions.cs @@ -1649,7 +1649,7 @@ internal static Cci.TypeReferenceWithAttributes GetTypeRefWithAttributes( } } - if (type.ContainsNullableReferenceTypes()) + if (type.NeedsNullableAttribute()) { SynthesizedAttributeData attr = moduleBuilder.SynthesizeNullableAttribute(declaringSymbol, type); if (attr != null) diff --git a/src/Compilers/CSharp/Portable/Symbols/TypeSymbolWithAnnotations.cs b/src/Compilers/CSharp/Portable/Symbols/TypeSymbolWithAnnotations.cs index 4e6c4276d8dc2..e0e492c5f55f5 100644 --- a/src/Compilers/CSharp/Portable/Symbols/TypeSymbolWithAnnotations.cs +++ b/src/Compilers/CSharp/Portable/Symbols/TypeSymbolWithAnnotations.cs @@ -284,7 +284,7 @@ public TypeSymbolWithAnnotations SetIsAnnotated(CSharpCompilation compilation) return CreateLazyNullableType(compilation, this); } - public TypeSymbolWithAnnotations AsNullableReferenceType(bool fromDeclaration) => _extensions.AsNullableReferenceType(this, fromDeclaration); + private TypeSymbolWithAnnotations AsNullableReferenceType() => _extensions.AsNullableReferenceType(this); public TypeSymbolWithAnnotations AsNotNullableReferenceType() => _extensions.AsNotNullableReferenceType(this); /// @@ -752,46 +752,58 @@ public bool Is(TypeParameterSymbol other) public TypeSymbolWithAnnotations WithTypeAndModifiers(TypeSymbol typeSymbol, ImmutableArray customModifiers) => _extensions.WithTypeAndModifiers(this, typeSymbol, customModifiers); - public bool ContainsNullableReferenceTypes() + public bool NeedsNullableAttribute() { - return ContainsNullableReferenceTypes(this, typeOpt: null); + return NeedsNullableAttribute(this, typeOpt: null); } - public static bool ContainsNullableReferenceTypes( + public static bool NeedsNullableAttribute( TypeSymbolWithAnnotations typeWithAnnotationsOpt, TypeSymbol typeOpt) { var type = TypeSymbolExtensions.VisitType( typeWithAnnotationsOpt, typeOpt, - typeWithAnnotationsPredicateOpt: (t, a, b) => t.NullableAnnotation.IsAnyNullable() && !t.TypeSymbol.IsErrorType() && !t.TypeSymbol.IsValueType, + typeWithAnnotationsPredicateOpt: (t, a, b) => t.NullableAnnotation != NullableAnnotation.Unknown && !t.TypeSymbol.IsErrorType() && !t.TypeSymbol.IsValueType, typePredicateOpt: null, arg: (object)null); return (object)type != null; } - public void AddNullableTransforms(ArrayBuilder transforms) + public void AddNullableTransforms(ArrayBuilder transforms) { var typeSymbol = TypeSymbol; - transforms.Add(NullableAnnotation.IsAnyNullable() && !typeSymbol.IsValueType); + byte flag; + + if (NullableAnnotation == NullableAnnotation.Unknown || typeSymbol.IsValueType) + { + flag = (byte)NullableAnnotation.Unknown; + } + else if (NullableAnnotation.IsAnyNullable()) + { + flag = (byte)NullableAnnotation.Nullable; + } + else + { + flag = (byte)NullableAnnotation.NotNullable; + } + + transforms.Add(flag); typeSymbol.AddNullableTransforms(transforms); } - public bool ApplyNullableTransforms(ImmutableArray transforms, INonNullTypesContext nonNullTypesContext, ref int position, out TypeSymbolWithAnnotations result) + public bool ApplyNullableTransforms(byte defaultTransformFlag, ImmutableArray transforms, ref int position, out TypeSymbolWithAnnotations result) { - Debug.Assert(nonNullTypesContext != null); - result = this; - bool isAnnotated; + byte transformFlag; if (transforms.IsDefault) { - // No explicit transforms. All reference types are unannotated. - isAnnotated = false; + transformFlag = defaultTransformFlag; } else if (position < transforms.Length) { - isAnnotated = transforms[position++]; + transformFlag = transforms[position++]; } else { @@ -801,7 +813,7 @@ public bool ApplyNullableTransforms(ImmutableArray transforms, INonNullTyp TypeSymbol oldTypeSymbol = TypeSymbol; TypeSymbol newTypeSymbol; - if (!oldTypeSymbol.ApplyNullableTransforms(transforms, nonNullTypesContext, ref position, out newTypeSymbol)) + if (!oldTypeSymbol.ApplyNullableTransforms(defaultTransformFlag, transforms, ref position, out newTypeSymbol)) { return false; } @@ -811,17 +823,23 @@ public bool ApplyNullableTransforms(ImmutableArray transforms, INonNullTyp result = result.WithTypeAndModifiers(newTypeSymbol, result.CustomModifiers); } - if (isAnnotated) + switch ((NullableAnnotation)transformFlag) { - result = result.AsNullableReferenceType(fromDeclaration: true); - } - else if (nonNullTypesContext.NonNullTypes == true) - { - result = result.AsNotNullableReferenceType(); - } - else if (result.NullableAnnotation != NullableAnnotation.Unknown && (!result.NullableAnnotation.IsAnyNullable() || !oldTypeSymbol.IsValueType)) - { - result = CreateNonLazyType(newTypeSymbol, NullableAnnotation.Unknown, result.CustomModifiers); + case NullableAnnotation.Nullable: + result = result.AsNullableReferenceType(); + break; + + case NullableAnnotation.NotNullable: + result = result.AsNotNullableReferenceType(); + break; + + default: + Debug.Assert((NullableAnnotation)transformFlag == NullableAnnotation.Unknown); + if (result.NullableAnnotation != NullableAnnotation.Unknown && (!result.NullableAnnotation.IsAnyNullable() || !oldTypeSymbol.IsNullableType())) + { + result = CreateNonLazyType(newTypeSymbol, NullableAnnotation.Unknown, result.CustomModifiers); + } + break; } return true; @@ -930,7 +948,7 @@ internal static Extensions CreateLazy(CSharpCompilation compilation, TypeSymbolW internal abstract TypeSymbol GetResolvedType(TypeSymbol defaultType); internal abstract ImmutableArray CustomModifiers { get; } - internal abstract TypeSymbolWithAnnotations AsNullableReferenceType(TypeSymbolWithAnnotations type, bool fromDeclaration); + internal abstract TypeSymbolWithAnnotations AsNullableReferenceType(TypeSymbolWithAnnotations type); internal abstract TypeSymbolWithAnnotations AsNotNullableReferenceType(TypeSymbolWithAnnotations type); internal abstract TypeSymbolWithAnnotations WithModifiers(TypeSymbolWithAnnotations type, ImmutableArray customModifiers); @@ -1007,9 +1025,9 @@ internal override TypeSymbolWithAnnotations WithTypeAndModifiers(TypeSymbolWithA return CreateNonLazyType(typeSymbol, type.NullableAnnotation, customModifiers); } - internal override TypeSymbolWithAnnotations AsNullableReferenceType(TypeSymbolWithAnnotations type, bool fromDeclaration) + internal override TypeSymbolWithAnnotations AsNullableReferenceType(TypeSymbolWithAnnotations type) { - return CreateNonLazyType(type._defaultType, fromDeclaration ? NullableAnnotation.Nullable : NullableAnnotation.NullableBasedOnAnalysis, _customModifiers); + return CreateNonLazyType(type._defaultType, NullableAnnotation.Nullable, _customModifiers); } internal override TypeSymbolWithAnnotations AsNotNullableReferenceType(TypeSymbolWithAnnotations type) @@ -1143,7 +1161,7 @@ internal override TypeSymbolWithAnnotations WithTypeAndModifiers(TypeSymbolWithA return CreateNonLazyType(typeSymbol, type.NullableAnnotation, customModifiers); } - internal override TypeSymbolWithAnnotations AsNullableReferenceType(TypeSymbolWithAnnotations type, bool fromDeclaration) + internal override TypeSymbolWithAnnotations AsNullableReferenceType(TypeSymbolWithAnnotations type) { return type; } diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf index 2605040599b67..fb84069a096e3 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf @@ -47,11 +47,6 @@ Type parameter '{1}' has the 'unmanaged' constraint so '{1}' cannot be used as a constraint for '{0}' - - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - - Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. @@ -307,11 +302,6 @@ unmanaged generic type constraints - - injected declaration - injected declaration - - <null> <null> diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf index 2e477a60b1e99..f96c357011abe 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf @@ -47,11 +47,6 @@ Type parameter '{1}' has the 'unmanaged' constraint so '{1}' cannot be used as a constraint for '{0}' - - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - - Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. @@ -307,11 +302,6 @@ unmanaged generic type constraints - - injected declaration - injected declaration - - <null> <NULL> diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf index 17201e1983248..ccefb78c82501 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf @@ -47,11 +47,6 @@ Type parameter '{1}' has the 'unmanaged' constraint so '{1}' cannot be used as a constraint for '{0}' - - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - - Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. @@ -307,11 +302,6 @@ unmanaged generic type constraints - - injected declaration - injected declaration - - <null> <NULL> diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf index 76eeb27a227e0..b7213bb5a887e 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf @@ -47,11 +47,6 @@ Type parameter '{1}' has the 'unmanaged' constraint so '{1}' cannot be used as a constraint for '{0}' - - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - - Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. @@ -307,11 +302,6 @@ unmanaged generic type constraints - - injected declaration - injected declaration - - <null> <Null> diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf index 8d5bc57003923..c723442e4045c 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf @@ -47,11 +47,6 @@ Type parameter '{1}' has the 'unmanaged' constraint so '{1}' cannot be used as a constraint for '{0}' - - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - - Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. @@ -307,11 +302,6 @@ unmanaged generic type constraints - - injected declaration - injected declaration - - <null> <Null> diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf index 3a5acdb049b17..bf6f2db55e5e4 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf @@ -47,11 +47,6 @@ Type parameter '{1}' has the 'unmanaged' constraint so '{1}' cannot be used as a constraint for '{0}' - - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - - Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. @@ -307,11 +302,6 @@ unmanaged generic type constraints - - injected declaration - injected declaration - - <null> <null> diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf index 20d9442eb1467..52df09b8cf973 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf @@ -47,11 +47,6 @@ Type parameter '{1}' has the 'unmanaged' constraint so '{1}' cannot be used as a constraint for '{0}' - - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - - Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. @@ -307,11 +302,6 @@ unmanaged generic type constraints - - injected declaration - injected declaration - - <null> <null> diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf index 4ece8f73e92f4..27c25bfaeb56e 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf @@ -47,11 +47,6 @@ Type parameter '{1}' has the 'unmanaged' constraint so '{1}' cannot be used as a constraint for '{0}' - - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - - Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. @@ -307,11 +302,6 @@ unmanaged generic type constraints - - injected declaration - injected declaration - - <null> <null> diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf index 929b19b9142f1..d0e823f3ecc79 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf @@ -47,11 +47,6 @@ Type parameter '{1}' has the 'unmanaged' constraint so '{1}' cannot be used as a constraint for '{0}' - - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - - Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. @@ -307,11 +302,6 @@ unmanaged generic type constraints - - injected declaration - injected declaration - - <null> <nulo> diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf index 3131e671ed5ce..6465bd1994ca7 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf @@ -47,11 +47,6 @@ Type parameter '{1}' has the 'unmanaged' constraint so '{1}' cannot be used as a constraint for '{0}' - - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - - Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. @@ -307,11 +302,6 @@ unmanaged generic type constraints - - injected declaration - injected declaration - - <null> <NULL> diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf index 35b7df1794bfa..566349b569b99 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf @@ -47,11 +47,6 @@ Type parameter '{1}' has the 'unmanaged' constraint so '{1}' cannot be used as a constraint for '{0}' - - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - - Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. @@ -307,11 +302,6 @@ unmanaged generic type constraints - - injected declaration - injected declaration - - <null> <null> diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf index 3210e370e7eaa..7ca3a8c796d1a 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf @@ -47,11 +47,6 @@ Type parameter '{1}' has the 'unmanaged' constraint so '{1}' cannot be used as a constraint for '{0}' - - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - - Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. @@ -307,11 +302,6 @@ unmanaged generic type constraints - - injected declaration - injected declaration - - <null> <null> diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf index 46b613200da94..42f0afffe55d6 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf @@ -47,11 +47,6 @@ Type parameter '{1}' has the 'unmanaged' constraint so '{1}' cannot be used as a constraint for '{0}' - - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - - Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. @@ -307,11 +302,6 @@ unmanaged generic type constraints - - injected declaration - injected declaration - - <null> <null> diff --git a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_Embedded.cs b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_Embedded.cs index b6f01e6239dd0..03306fdbb17ed 100644 --- a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_Embedded.cs +++ b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_Embedded.cs @@ -10,70 +10,6 @@ namespace Microsoft.CodeAnalysis.CSharp.UnitTests { public class AttributeTests_Embedded : CSharpTestBase { - [Fact] - public void EmbeddedAttributeNamespace() - { - var code = @" -namespace Microsoft.CodeAnalysis.EmbeddedAttribute -{ - class C { } -} -namespace TestReference -{ - [Microsoft.CodeAnalysis.Embedded] - internal class TestType1 { } - - [Microsoft.CodeAnalysis.EmbeddedAttribute] - internal class TestType2 { } - - internal class TestType3 { } -}"; - - CreateCompilation(code).VerifyEmitDiagnostics( - // (11,29): error CS0616: 'Microsoft.CodeAnalysis.EmbeddedAttribute' is not an attribute class - // [Microsoft.CodeAnalysis.EmbeddedAttribute] - Diagnostic(ErrorCode.ERR_NotAnAttributeClass, "EmbeddedAttribute").WithArguments("Microsoft.CodeAnalysis.EmbeddedAttribute").WithLocation(11, 29), - // (8,29): error CS0616: 'Microsoft.CodeAnalysis.EmbeddedAttribute' is not an attribute class - // [Microsoft.CodeAnalysis.Embedded] - Diagnostic(ErrorCode.ERR_NotAnAttributeClass, "Embedded").WithArguments("Microsoft.CodeAnalysis.EmbeddedAttribute").WithLocation(8, 29) - ); - } - - [Fact] - public void EmbeddedAttributeInMergedNamespaceSymbol() - { - var reference_cs = @" -namespace Microsoft.CodeAnalysis -{ - internal class EmbeddedAttribute : System.Attribute { } -}"; - var reference = CreateCompilation(new[] { reference_cs }); - reference.VerifyDiagnostics(); - - var comp_cs = @" -namespace Microsoft.CodeAnalysis.EmbeddedAttribute -{ - class C { } -}"; - var comp = CreateCompilation(new[] { comp_cs }, options: WithNonNullTypesTrue(), references: new[] { reference.ToMetadataReference() }); - comp.VerifyEmitDiagnostics( - // error CS0518: Predefined type 'Microsoft.CodeAnalysis.EmbeddedAttribute' is not defined or imported - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("Microsoft.CodeAnalysis.EmbeddedAttribute").WithLocation(1, 1) - ); - - var type = comp.GetWellKnownType(WellKnownType.Microsoft_CodeAnalysis_EmbeddedAttribute); - Assert.True(type.IsErrorType()); - - // https://github.com/dotnet/roslyn/issues/29683 CSharpCompilation.AbstractSymbolSearcher needs to inject namespaces and types too - //Assert.False(comp.ContainsSymbolsWithName("NonNullTypesAttribute", SymbolFilter.Type)); - //Assert.Empty(comp.GetSymbolsWithName("NonNullTypesAttribute", SymbolFilter.Type)); - //Assert.Empty(comp.GetSymbolsWithName(n => n == "NonNullTypesAttribute", SymbolFilter.Type)); - - //Assert.True(comp.ContainsSymbolsWithName("EmbeddedAttribute", SymbolFilter.Type)); - //Assert.Equal("Microsoft.CodeAnalysis.EmbeddedAttribute", comp.GetSymbolsWithName("EmbeddedAttribute", SymbolFilter.Type).Single().ToTestDisplayString()); - //Assert.Equal("Microsoft.CodeAnalysis.EmbeddedAttribute", comp.GetSymbolsWithName(n => n == "EmbeddedAttribute", SymbolFilter.Type).Single().ToTestDisplayString()); - } - [Fact] public void ReferencingEmbeddedAttributesFromTheSameAssemblySucceeds() { @@ -178,8 +114,6 @@ public static void Main() }"; CreateCompilation(code, references: new[] { reference }, assemblyName: "Source").VerifyDiagnostics( - // error CS0101: The namespace 'Microsoft.CodeAnalysis' already contains a definition for 'EmbeddedAttribute' - Diagnostic(ErrorCode.ERR_DuplicateNameInNS).WithArguments("EmbeddedAttribute", "Microsoft.CodeAnalysis").WithLocation(1, 1), // (6,38): error CS0234: The type or namespace name 'TestType1' does not exist in the namespace 'TestReference' (are you missing an assembly reference?) // var obj1 = new TestReference.TestType1(); Diagnostic(ErrorCode.ERR_DottedTypeNameNotFoundInNS, "TestType1").WithArguments("TestType1", "TestReference").WithLocation(6, 38), @@ -298,8 +232,8 @@ public void M(in int p) }"; CreateCompilation(code, references: new[] { moduleRef }).VerifyEmitDiagnostics( - // error CS0101: The namespace 'Microsoft.CodeAnalysis' already contains a definition for 'EmbeddedAttribute' - Diagnostic(ErrorCode.ERR_DuplicateNameInNS).WithArguments("EmbeddedAttribute", "Microsoft.CodeAnalysis").WithLocation(1, 1)); + // error CS8004: Type 'EmbeddedAttribute' exported from module 'testModule.netmodule' conflicts with type declared in primary module of this assembly. + Diagnostic(ErrorCode.ERR_ExportedTypeConflictsWithDeclaration).WithArguments("Microsoft.CodeAnalysis.EmbeddedAttribute", "testModule.netmodule").WithLocation(1, 1)); } [Fact] @@ -322,12 +256,8 @@ public void M(in int p) }"; CreateCompilation(code, references: new[] { reference }).VerifyEmitDiagnostics( - // (2,99): warning CS0436: The type 'EmbeddedAttribute' in 'injected declaration' conflicts with the imported type 'EmbeddedAttribute' in 'reference, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. Using the type defined in 'injected declaration'. - // [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.CodeAnalysis.EmbeddedAttribute))] - Diagnostic(ErrorCode.WRN_SameFullNameThisAggAgg, "EmbeddedAttribute").WithArguments("injected declaration", "Microsoft.CodeAnalysis.EmbeddedAttribute", "reference, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", "Microsoft.CodeAnalysis.EmbeddedAttribute").WithLocation(2, 99), - // (2,12): error CS0729: Type 'EmbeddedAttribute' is defined in this assembly, but a type forwarder is specified for it - // [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.CodeAnalysis.EmbeddedAttribute))] - Diagnostic(ErrorCode.ERR_ForwardedTypeInThisAssembly, "System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.CodeAnalysis.EmbeddedAttribute))").WithArguments("Microsoft.CodeAnalysis.EmbeddedAttribute").WithLocation(2, 12)); + // error CS8006: Forwarded type 'EmbeddedAttribute' conflicts with type declared in primary module of this assembly. + Diagnostic(ErrorCode.ERR_ForwardedTypeConflictsWithDeclaration).WithArguments("Microsoft.CodeAnalysis.EmbeddedAttribute").WithLocation(1, 1)); } [Fact] @@ -382,6 +312,8 @@ public void M(in object x) { } // should trigger synthesizing IsReadOnly }"; CreateEmptyCompilation(code).VerifyEmitDiagnostics(CodeAnalysis.Emit.EmitOptions.Default.WithRuntimeMetadataVersion("v4.0.30319"), + // error CS0518: Predefined type 'System.Attribute' is not defined or imported + Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Attribute").WithLocation(1, 1), // error CS0518: Predefined type 'System.Attribute' is not defined or imported Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Attribute").WithLocation(1, 1)); } @@ -449,6 +381,8 @@ public class Test // public class Test Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "Test").WithArguments("System.Void").WithLocation(7, 14), // error CS0518: Predefined type 'System.Void' is not defined or imported + Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Void").WithLocation(1, 1), + // error CS0518: Predefined type 'System.Void' is not defined or imported Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Void").WithLocation(1, 1)); } @@ -471,6 +405,8 @@ public void M(in object x) { } // should trigger synthesizing IsReadOnly }"; CreateEmptyCompilation(code).VerifyEmitDiagnostics(CodeAnalysis.Emit.EmitOptions.Default.WithRuntimeMetadataVersion("v4.0.30319"), + // 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 Diagnostic(ErrorCode.ERR_BadCtorArgCount).WithArguments("System.Attribute", "0").WithLocation(1, 1)); } diff --git a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_NonNullTypes.cs b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_NonNullTypes.cs deleted file mode 100644 index 9d2d77534492b..0000000000000 --- a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_NonNullTypes.cs +++ /dev/null @@ -1,445 +0,0 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.CodeAnalysis.CSharp.Test.Utilities; -using Microsoft.CodeAnalysis.Test.Utilities; -using System.Collections.Immutable; -using System.Linq; -using Xunit; - -namespace Microsoft.CodeAnalysis.CSharp.UnitTests -{ - public class AttributeTests_NonNullTypes : CSharpTestBase - { - [Fact] - public void EmbeddedAttributeInAddedModule() - { - var module = CreateCompilation(@" -namespace Microsoft.CodeAnalysis -{ - public class EmbeddedAttribute : System.Attribute { } -} -", options: TestOptions.ReleaseModule); - - var reference = ModuleMetadata.CreateFromImage(module.EmitToArray()).GetReference(); - - var comp = CreateCompilation("", options: WithNonNullTypesTrue(), references: new[] { reference }); - comp.VerifyEmitDiagnostics( - // error CS0101: The namespace 'Microsoft.CodeAnalysis' already contains a definition for 'EmbeddedAttribute' - Diagnostic(ErrorCode.ERR_DuplicateNameInNS).WithArguments("EmbeddedAttribute", "Microsoft.CodeAnalysis").WithLocation(1, 1) - ); - } - - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/29732 Crashing")] - public void EmbeddedAttributeInAddedModule_Injected() - { - var code = "[module: System.Runtime.CompilerServices.NonNullTypes]"; - - var module = CreateCompilation(code, options: TestOptions.ReleaseModule); - var reference = ModuleMetadata.CreateFromImage(module.EmitToArray()).GetReference(); - - var comp = CreateCompilation(code, references: new[] { reference }); - comp.VerifyEmitDiagnostics(); - } - - [Fact] - public void NonNullTypesAttributeNamespace() - { - var code = @" -namespace System.Runtime.CompilerServices.NonNullTypesAttribute -{ - class C { } -} - -[System.Runtime.CompilerServices.NonNullTypes] -internal class TestType1 { } - -[System.Runtime.CompilerServices.NonNullTypesAttribute(false)] -internal class TestType2 { } -"; - - var comp = CreateCompilation(code); - comp.VerifyEmitDiagnostics( - // (7,34): error CS0616: 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not an attribute class - // [System.Runtime.CompilerServices.NonNullTypes] - Diagnostic(ErrorCode.ERR_NotAnAttributeClass, "NonNullTypes").WithArguments("System.Runtime.CompilerServices.NonNullTypesAttribute").WithLocation(7, 34), - // (10,34): error CS0616: 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not an attribute class - // [System.Runtime.CompilerServices.NonNullTypesAttribute(false)] - Diagnostic(ErrorCode.ERR_NotAnAttributeClass, "NonNullTypesAttribute").WithArguments("System.Runtime.CompilerServices.NonNullTypesAttribute").WithLocation(10, 34) - ); - Assert.Equal(SymbolKind.Namespace, comp.GlobalNamespace.GetMember("System.Runtime.CompilerServices.NonNullTypesAttribute").Kind); - } - - [Fact] - public void NonNullTypesAttributeNamespace_WithoutUsage() - { - var code = @" -namespace System.Runtime.CompilerServices.NonNullTypesAttribute -{ - class C { } -} -"; - - var comp = CreateCompilation(code); - comp.VerifyEmitDiagnostics(); - Assert.Equal(SymbolKind.Namespace, comp.GlobalNamespace.GetMember("System.Runtime.CompilerServices.NonNullTypesAttribute").Kind); - } - - [Fact] - public void ReferencingNonNullTypesAttributesFromTheSameAssemblyAllowed() - { - var code = @" -namespace System.Runtime.CompilerServices -{ - internal class NonNullTypesAttribute : System.Attribute { public NonNullTypesAttribute(bool flag = true) { } } -} - -" + NonNullTypesOn() + @" -internal class TestType1 { } - -" + NonNullTypesOff() + @" -internal class TestType2 { } -"; - - var comp = CreateCompilation(code); - comp.VerifyEmitDiagnostics(); - Assert.True(comp.GetMember("TestType1").NonNullTypes); - Assert.False(comp.GetMember("TestType2").NonNullTypes); - - CompileAndVerify(comp, symbolValidator: - (m) => - { - Assert.Same(m, m.GlobalNamespace.GetMember("TestType1").GetAttributes().Single().AttributeClass.ContainingModule); - Assert.Same(m, m.GlobalNamespace.GetMember("TestType2").GetAttributes().Single().AttributeClass.ContainingModule); - Assert.True(m.GlobalNamespace.GetMember("TestType1").NonNullTypes); - Assert.False(m.GlobalNamespace.GetMember("TestType2").NonNullTypes); - } - ); - - } - - [Fact] - public void CannotReferenceNonNullTypesAttributesFromADifferentAssembly_Internal() - { - var reference = CreateCompilation(@" -[assembly: System.Runtime.CompilerServices.InternalsVisibleToAttribute(""Source"")] -namespace System.Runtime.CompilerServices -{ - internal class NonNullTypesAttribute : System.Attribute { public NonNullTypesAttribute(bool flag = true) { } } -} - -" + NonNullTypesOn() + @" -internal class TestType1 { } - -" + NonNullTypesOn() + @" -internal class TestType2 { } -"); - Assert.Empty(reference.GetMember("TestType1").GetAttributes()); - Assert.Empty(reference.GetMember("TestType2").GetAttributes()); - - CompileAndVerify(reference, symbolValidator: - (m) => - { - Assert.Same(m, m.GlobalNamespace.GetMember("TestType1").GetAttributes().Single().AttributeClass.ContainingModule); - Assert.Same(m, m.GlobalNamespace.GetMember("TestType2").GetAttributes().Single().AttributeClass.ContainingModule); - } - ); - - // NonNullTypesAttribute from referenced assembly is ignored, and we use the injected one instead - var comp = CreateCompilation("", options: WithNonNullTypesTrue(), references: new[] { reference.ToMetadataReference() }, assemblyName: "Source"); - comp.VerifyDiagnostics(); - Assert.Empty(comp.SourceModule.GetAttributes()); - Assert.True(comp.SourceModule.NonNullTypes); - - CompileAndVerify(comp, symbolValidator: - (m) => - { - Assert.Same(m, m.GetAttributes().Single().AttributeClass.ContainingModule); - Assert.True(m.NonNullTypes); - } - ); - - var system = (INamespaceSymbol)comp.GlobalNamespace.GetMember("System"); - Assert.Equal(NamespaceKind.Compilation, system.NamespaceKind); - } - - [Fact] - public void CannotReferenceNonNullTypesAttributesFromADifferentAssembly_Module() - { - var module = CreateCompilation(@" -namespace System.Runtime.CompilerServices -{ - internal class NonNullTypesAttribute : System.Attribute { public NonNullTypesAttribute(bool flag = true) { } } -} - -" + NonNullTypesOn() + @" -internal class TestType1 { } -", options: TestOptions.ReleaseModule); - - var reference = ModuleMetadata.CreateFromImage(module.EmitToArray()).GetReference(); - - var system = (INamespaceSymbol)module.GlobalNamespace.GetMember("System"); - Assert.Equal(NamespaceKind.Compilation, system.NamespaceKind); - - // NonNullTypesAttribute from module conflicts with injected symbol - var comp = CreateCompilation("", references: new[] { reference }, options: WithNonNullTypesTrue()); - comp.VerifyDiagnostics( - // error CS0101: The namespace 'System.Runtime.CompilerServices' already contains a definition for 'NonNullTypesAttribute' - Diagnostic(ErrorCode.ERR_DuplicateNameInNS).WithArguments("NonNullTypesAttribute", "System.Runtime.CompilerServices").WithLocation(1, 1) - ); - - system = (INamespaceSymbol)comp.GlobalNamespace.GetMember("System"); - Assert.Equal(NamespaceKind.Compilation, system.NamespaceKind); - } - - [Fact] - public void CannotReferenceNonNullTypesAttributesFromADifferentAssembly_Public() - { - var reference = CreateCompilation(@" -namespace System.Runtime.CompilerServices -{ - public class NonNullTypesAttribute : System.Attribute { public NonNullTypesAttribute(bool flag = true) { } } -} - -" + NonNullTypesOn() + @" -public class TestType1 { } - -" + NonNullTypesOff() + @" -public class TestType2 { } -"); - Assert.Empty(reference.GetMember("TestType1").GetAttributes()); - Assert.Empty(reference.GetMember("TestType2").GetAttributes()); - - CompileAndVerify(reference, symbolValidator: - (m) => - { - Assert.Same(m, m.GlobalNamespace.GetMember("TestType1").GetAttributes().Single().AttributeClass.ContainingModule); - Assert.Same(m, m.GlobalNamespace.GetMember("TestType2").GetAttributes().Single().AttributeClass.ContainingModule); - }); - - // NonNullTypesAttribute from referenced assembly is ignored, and we use the injected one instead - var comp = CreateCompilation("", references: new[] { reference.ToMetadataReference() }, options: WithNonNullTypesTrue()); - - Assert.Empty(comp.SourceModule.GetAttributes()); - - CompileAndVerify(comp, symbolValidator: - (m) => - { - Assert.Same(m, m.GetAttributes().Single().AttributeClass.ContainingModule); - Assert.True(m.NonNullTypes); - }); - } - - [Fact] - public void CanReferenceNonNullTypesAttributesFromADifferentAssemblyViaExternDeclaration() - { - var reference = CreateCompilation(@" -namespace System.Runtime.CompilerServices -{ - public class NonNullTypesAttribute : System.Attribute { public NonNullTypesAttribute(bool flag = true) { } } -} - -[System.Runtime.CompilerServices.NonNullTypes] -public class TestType1 { } -"); - Assert.False(reference.GetMember("TestType1").GetAttributes().Single().AttributeClass.IsImplicitlyDeclared); - - var code = @" -extern alias Reference; -[module: Reference::System.Runtime.CompilerServices.NonNullTypes] -class C -{ - string? M() => throw null; -} -"; - - var comp = CreateCompilation(code, references: new[] { reference.ToMetadataReference(aliases: ImmutableArray.Create("Reference")) }); - comp.VerifyDiagnostics( - // (3,10): error CS8635: Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - // [module: Reference::System.Runtime.CompilerServices.NonNullTypes] - Diagnostic(ErrorCode.ERR_ExplicitNonNullTypesAttribute, "Reference::System.Runtime.CompilerServices.NonNullTypes").WithLocation(3, 10), - // (6,11): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' context. - // string? M() => throw null; - Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(6, 11) - ); - - Assert.False(comp.SourceModule.GetAttributes().Single().AttributeClass.IsImplicitlyDeclared); - Assert.Null(comp.SourceModule.NonNullTypes); - } - - [Fact] - public void NonNullTypesAttributeInSourceCanBeUsed() - { - var code = @" -namespace System.Runtime.CompilerServices -{ - public class NonNullTypesAttribute : System.Attribute { public NonNullTypesAttribute(bool flag = true) { } } -}"; - - var comp = CreateCompilation(code, options: WithNonNullTypesTrue()); - comp.VerifyEmitDiagnostics(); - Assert.True(comp.SourceModule.NonNullTypes); - Assert.Empty(comp.SourceModule.GetAttributes()); - Assert.True(comp.SourceModule.NonNullTypes); - - CompileAndVerify(comp, symbolValidator: - (m) => - { - Assert.Same(m, m.GetAttributes().Single().AttributeClass.ContainingModule); - Assert.True(m.NonNullTypes); - }); - } - - [Fact] - public void NonNullTypesAttributeInReferencedModuleCausesAmbiguity() - { - var module = CreateCompilation(options: TestOptions.ReleaseModule, assemblyName: "testModule", source: @" -namespace System.Runtime.CompilerServices -{ - public class NonNullTypesAttribute : System.Attribute { public NonNullTypesAttribute(bool flag = true) { } } -}"); - - var moduleRef = ModuleMetadata.CreateFromImage(module.EmitToArray()).GetReference(); - - var code = " /* NonNullTypesAttribute is injected when not present in source */ "; - - // It is okay to have a duplicate of NonNullTypesAttribute when the other comes from a referenced assembly, - // but we don't allow such collisions when the other comes from an added module. - - CreateCompilation(code, references: new[] { moduleRef }).VerifyEmitDiagnostics( - // error CS0101: The namespace 'System.Runtime.CompilerServices' already contains a definition for 'NonNullTypesAttribute' - Diagnostic(ErrorCode.ERR_DuplicateNameInNS).WithArguments("NonNullTypesAttribute", "System.Runtime.CompilerServices").WithLocation(1, 1)); - } - - [Fact] - public void NonNullTypesAttributeForwardedToAnotherAssemblyShouldTriggerAnError() - { - var reference = CreateCompilation(@" -namespace System.Runtime.CompilerServices -{ - public class NonNullTypesAttribute : System.Attribute { public NonNullTypesAttribute(bool flag = true) { } } -}", assemblyName: "reference").ToMetadataReference(); - - var code = @" -[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.CompilerServices.NonNullTypesAttribute))] - - - -class Test -{ -}"; - - CreateCompilation(code, references: new[] { reference }, - options: WithNonNullTypesTrue() // This should trigger generating another NonNullTypesAttribute - ).VerifyEmitDiagnostics( - // (2,12): error CS0729: Type 'NonNullTypesAttribute' is defined in this assembly, but a type forwarder is specified for it - // [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.CompilerServices.NonNullTypesAttribute))] - Diagnostic(ErrorCode.ERR_ForwardedTypeInThisAssembly, "System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.CompilerServices.NonNullTypesAttribute))").WithArguments("System.Runtime.CompilerServices.NonNullTypesAttribute").WithLocation(2, 12)); - } - - [Fact] - public void CompilerShouldIgnorePublicNonNullTypesAttributesInReferencedAssemblies() - { - var reference = CreateCompilation(assemblyName: "testRef", source: @" -namespace System.Runtime.CompilerServices -{ - public class NonNullTypesAttribute : System.Attribute { public NonNullTypesAttribute(bool flag = true) { } } -} -public class C { } -").ToMetadataReference(); - - var code = @" -public class D : C { }"; - - CompileAndVerify(code, options: WithNonNullTypesTrue(), references: new[] { reference }, symbolValidator: module => - { - var attributeName = AttributeDescription.NonNullTypesAttribute.FullName; - - var referenceAttribute = module.GetReferencedAssemblySymbols().Single(assembly => assembly.Name == "testRef").GetTypeByMetadataName(attributeName); - Assert.NotNull(referenceAttribute); - - var generatedAttribute = module.ContainingAssembly.GetTypeByMetadataName(attributeName); - Assert.NotNull(generatedAttribute); - - Assert.False(referenceAttribute.Equals(generatedAttribute)); - }); - } - - [Fact] - public void SynthesizingAttributeRequiresSystemAttribute_NoSystemAttribute() - { - var code = @" - - -namespace System -{ - public class Object {} - public class Void {} -}"; - - CreateEmptyCompilation(code, - options: WithNonNullTypesTrue() // This should trigger generating NonNullTypesAttribute - ).VerifyEmitDiagnostics(CodeAnalysis.Emit.EmitOptions.Default.WithRuntimeMetadataVersion("v4.0.30319"), - // error CS0518: Predefined type 'System.Boolean' is not defined or imported - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Boolean").WithLocation(1, 1), - // error CS0518: Predefined type 'System.Attribute' is not defined or imported - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Attribute").WithLocation(1, 1), - // error CS0518: Predefined type 'System.Boolean' is not defined or imported - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Boolean").WithLocation(1, 1), - // error CS0656: Missing compiler required member 'System.AttributeUsageAttribute..ctor' - Diagnostic(ErrorCode.ERR_MissingPredefinedMember).WithArguments("System.AttributeUsageAttribute", ".ctor").WithLocation(1, 1), - // error CS0518: Predefined type 'System.Attribute' is not defined or imported - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Attribute").WithLocation(1, 1), - // error CS0518: Predefined type 'System.Attribute' is not defined or imported - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Attribute").WithLocation(1, 1)); - } - - [Fact] - public void SynthesizingAttributeRequiresSystemAttribute_NoSystemObject() - { - var code = @" - - -namespace System -{ - public class Attribute {} - public class Void {} -}"; - - CreateEmptyCompilation(code, - options: WithNonNullTypesTrue() // This should trigger generating NonNullTypesAttribute - ).VerifyEmitDiagnostics(CodeAnalysis.Emit.EmitOptions.Default.WithRuntimeMetadataVersion("v4.0.30319"), - // (6,18): error CS0518: Predefined type 'System.Object' is not defined or imported - // public class Attribute {} - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "Attribute").WithArguments("System.Object").WithLocation(6, 18), - // (7,18): error CS0518: Predefined type 'System.Object' is not defined or imported - // public class Void {} - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "Void").WithArguments("System.Object").WithLocation(7, 18), - // (6,18): error CS1729: 'object' does not contain a constructor that takes 0 arguments - // public class Attribute {} - Diagnostic(ErrorCode.ERR_BadCtorArgCount, "Attribute").WithArguments("object", "0").WithLocation(6, 18), - // (7,18): error CS1729: 'object' does not contain a constructor that takes 0 arguments - // public class Void {} - Diagnostic(ErrorCode.ERR_BadCtorArgCount, "Void").WithArguments("object", "0").WithLocation(7, 18)); - } - - [Fact] - public void SynthesizingAttributeRequiresSystemAttribute_NoSystemVoid() - { - var code = @" - - -namespace System -{ - public class Attribute {} - public class Object {} -}"; - - CreateEmptyCompilation(code, - options: WithNonNullTypesTrue() // This should trigger generating NonNullTypesAttribute - ).VerifyEmitDiagnostics(CodeAnalysis.Emit.EmitOptions.Default.WithRuntimeMetadataVersion("v4.0.30319"), - // (6,18): error CS0518: Predefined type 'System.Void' is not defined or imported - // public class Attribute {} - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "Attribute").WithArguments("System.Void").WithLocation(6, 18)); - } - } -} diff --git a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_Nullable.cs b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_Nullable.cs index 5de959c452062..8f4232d1da2cf 100644 --- a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_Nullable.cs +++ b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_Nullable.cs @@ -34,8 +34,8 @@ public void ExplicitAttributeFromSource() { public sealed class NullableAttribute : Attribute { - public NullableAttribute() { } - public NullableAttribute(bool[] b) { } + public NullableAttribute(byte a) { } + public NullableAttribute(byte[] b) { } } } class C @@ -54,8 +54,8 @@ public void ExplicitAttributeFromMetadata() { public sealed class NullableAttribute : Attribute { - public NullableAttribute() { } - public NullableAttribute(bool[] b) { } + public NullableAttribute(byte a) { } + public NullableAttribute(byte[] b) { } } }"; var comp0 = CreateCompilation(source0, parseOptions: TestOptions.Regular7); @@ -78,7 +78,7 @@ public void ExplicitAttribute_MissingParameterlessConstructor() { public sealed class NullableAttribute : Attribute { - public NullableAttribute(bool[] b) { } + public NullableAttribute(byte[] b) { } } } class C @@ -87,6 +87,9 @@ static void F(object? x, object?[] y) { } }"; var comp = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue(), parseOptions: TestOptions.Regular8); comp.VerifyEmitDiagnostics( + // (5,34): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.NullableAttribute..ctor' + // public NullableAttribute(byte[] b) { } + Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "byte[] b").WithArguments("System.Runtime.CompilerServices.NullableAttribute", ".ctor").WithLocation(5, 34), // (10,19): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.NullableAttribute..ctor' // static void F(object? x, object?[] y) { } Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "object? x").WithArguments("System.Runtime.CompilerServices.NullableAttribute", ".ctor").WithLocation(10, 19), @@ -137,6 +140,9 @@ static void F(object? x, object?[] y) { } }"; var comp = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue(), parseOptions: TestOptions.Regular8); comp.VerifyEmitDiagnostics( + // (5,34): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.NullableAttribute..ctor' + // public NullableAttribute(string[] b) { } + Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "string[] b").WithArguments("System.Runtime.CompilerServices.NullableAttribute", ".ctor").WithLocation(5, 34), // (10,19): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.NullableAttribute..ctor' // static void F(object? x, object?[] y) { } Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "object? x").WithArguments("System.Runtime.CompilerServices.NullableAttribute", ".ctor").WithLocation(10, 19), @@ -146,7 +152,7 @@ static void F(object? x, object?[] y) { } } [Fact] - public void NullableAttribute_MissingBoolean() + public void NullableAttribute_MissingByte() { var source0 = @"namespace System @@ -174,8 +180,8 @@ public class Attribute // (3,11): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' context. // object? F() => null; 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)); + // error CS0518: Predefined type 'System.Byte' is not defined or imported + Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Byte").WithLocation(1, 1)); } [Fact] @@ -187,7 +193,7 @@ public void NullableAttribute_MissingAttribute() public class Object { } public abstract class ValueType { } public struct Void { } - public struct Boolean { } + public struct Byte { } }"; var comp0 = CreateEmptyCompilation(source0, parseOptions: TestOptions.Regular7); var ref0 = comp0.EmitToImageReference(); @@ -206,6 +212,8 @@ public struct Boolean { } // object? F() => null; 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), + // error CS0518: Predefined type 'System.Attribute' is not defined or imported Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Attribute").WithLocation(1, 1)); } @@ -219,6 +227,7 @@ public class Object { } public abstract class ValueType { } public struct Void { } public struct Boolean { } + public struct Byte { } public class Attribute { static Attribute() { } @@ -244,6 +253,8 @@ public Attribute(object o) { } // 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 + Diagnostic(ErrorCode.ERR_BadCtorArgCount).WithArguments("System.Attribute", "0").WithLocation(1, 1), + // error CS1729: 'Attribute' does not contain a constructor that takes 0 arguments Diagnostic(ErrorCode.ERR_BadCtorArgCount).WithArguments("System.Attribute", "0").WithLocation(1, 1)); } @@ -350,7 +361,7 @@ void local(T t) where T : C CompileAndVerify(comp, symbolValidator: module => { var assembly = module.ContainingAssembly; - Assert.Null(assembly.GetTypeByMetadataName("System.Runtime.CompilerServices.NullableAttribute")); + Assert.NotNull(assembly.GetTypeByMetadataName("System.Runtime.CompilerServices.NullableAttribute")); }); } @@ -423,7 +434,7 @@ public class B2 : A AssertNoNullableAttribute(type.GetAttributes()); type = module.ContainingAssembly.GetTypeByMetadataName("B1"); AssertNoNullableAttribute(type.BaseType().GetAttributes()); - AssertNoNullableAttribute(type.GetAttributes()); + AssertNullableAttribute(type.GetAttributes()); type = module.ContainingAssembly.GetTypeByMetadataName("B2"); AssertNoNullableAttribute(type.BaseType().GetAttributes()); AssertNullableAttribute(type.GetAttributes()); @@ -473,10 +484,10 @@ public class B : I var reader = assembly.GetMetadataReader(); var typeDef = GetTypeDefinitionByName(reader, "A"); var interfaceImpl = reader.GetInterfaceImplementation(typeDef.GetInterfaceImplementations().Single()); - AssertAttributes(reader, interfaceImpl.GetCustomAttributes()); + AssertAttributes(reader, interfaceImpl.GetCustomAttributes(), "MethodDefinition:Void System.Runtime.CompilerServices.NullableAttribute..ctor(Byte[])"); typeDef = GetTypeDefinitionByName(reader, "B"); interfaceImpl = reader.GetInterfaceImplementation(typeDef.GetInterfaceImplementations().Single()); - AssertAttributes(reader, interfaceImpl.GetCustomAttributes(), "MethodDefinition:Void System.Runtime.CompilerServices.NullableAttribute..ctor(Boolean[])"); + AssertAttributes(reader, interfaceImpl.GetCustomAttributes(), "MethodDefinition:Void System.Runtime.CompilerServices.NullableAttribute..ctor(Byte[])"); }); var source2 = @"class C @@ -530,7 +541,7 @@ public class B : I<(object X, object? Y)> interfaceImpl = reader.GetInterfaceImplementation(typeDef.GetInterfaceImplementations().Single()); AssertAttributes(reader, interfaceImpl.GetCustomAttributes(), "MemberReference:Void System.Runtime.CompilerServices.TupleElementNamesAttribute..ctor(String[])", - "MethodDefinition:Void System.Runtime.CompilerServices.NullableAttribute..ctor(Boolean[])"); + "MethodDefinition:Void System.Runtime.CompilerServices.NullableAttribute..ctor(Byte[])"); }); var source2 = @@ -577,11 +588,11 @@ public class D where T : A var typeDef = GetTypeDefinitionByName(reader, "C`1"); var typeParameter = reader.GetGenericParameter(typeDef.GetGenericParameters()[0]); var constraint = reader.GetGenericParameterConstraint(typeParameter.GetConstraints()[0]); - AssertAttributes(reader, constraint.GetCustomAttributes(), "MethodDefinition:Void System.Runtime.CompilerServices.NullableAttribute..ctor()"); + AssertAttributes(reader, constraint.GetCustomAttributes(), "MethodDefinition:Void System.Runtime.CompilerServices.NullableAttribute..ctor(Byte)"); typeDef = GetTypeDefinitionByName(reader, "D`1"); typeParameter = reader.GetGenericParameter(typeDef.GetGenericParameters()[0]); constraint = reader.GetGenericParameterConstraint(typeParameter.GetConstraints()[0]); - AssertAttributes(reader, constraint.GetCustomAttributes()); + AssertAttributes(reader, constraint.GetCustomAttributes(), "MethodDefinition:Void System.Runtime.CompilerServices.NullableAttribute..ctor(Byte)"); }); var source2 = @@ -690,11 +701,11 @@ public class C where T : A var typeDef = GetTypeDefinitionByName(reader, "B`1"); var typeParameter = reader.GetGenericParameter(typeDef.GetGenericParameters()[0]); var constraint = reader.GetGenericParameterConstraint(typeParameter.GetConstraints()[0]); - AssertAttributes(reader, constraint.GetCustomAttributes(), "MethodDefinition:Void System.Runtime.CompilerServices.NullableAttribute..ctor(Boolean[])"); + AssertAttributes(reader, constraint.GetCustomAttributes(), "MethodDefinition:Void System.Runtime.CompilerServices.NullableAttribute..ctor(Byte[])"); typeDef = GetTypeDefinitionByName(reader, "C`1"); typeParameter = reader.GetGenericParameter(typeDef.GetGenericParameters()[0]); constraint = reader.GetGenericParameterConstraint(typeParameter.GetConstraints()[0]); - AssertAttributes(reader, constraint.GetCustomAttributes()); + AssertAttributes(reader, constraint.GetCustomAttributes(), "MethodDefinition:Void System.Runtime.CompilerServices.NullableAttribute..ctor(Byte)"); }); var source2 = @@ -749,7 +760,7 @@ public void EmitAttribute_Constraint_TypeParameter() var typeDef = GetTypeDefinitionByName(reader, "C`2"); var typeParameter = reader.GetGenericParameter(typeDef.GetGenericParameters()[1]); var constraint = reader.GetGenericParameterConstraint(typeParameter.GetConstraints()[0]); - AssertAttributes(reader, constraint.GetCustomAttributes(), "MethodDefinition:Void System.Runtime.CompilerServices.NullableAttribute..ctor()"); + AssertAttributes(reader, constraint.GetCustomAttributes(), "MethodDefinition:Void System.Runtime.CompilerServices.NullableAttribute..ctor(Byte)"); }); var source2 = @@ -1278,6 +1289,12 @@ public void ModuleMissingAttribute_PropertyParameters() }"; var comp = CreateCompilation(new[] { source }, parseOptions: TestOptions.Regular8, options: WithNonNullTypesTrue(TestOptions.ReleaseModule)); comp.VerifyEmitDiagnostics( + // (3,5): error CS0518: Predefined type 'System.Runtime.CompilerServices.NullableAttribute' is not defined or imported + // object this[object x, object? y] => throw new System.NotImplementedException(); + Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "object").WithArguments("System.Runtime.CompilerServices.NullableAttribute").WithLocation(3, 5), + // (3,17): error CS0518: Predefined type 'System.Runtime.CompilerServices.NullableAttribute' is not defined or imported + // object this[object x, object? y] => throw new System.NotImplementedException(); + Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "object x").WithArguments("System.Runtime.CompilerServices.NullableAttribute").WithLocation(3, 17), // (3,27): error CS0518: Predefined type 'System.Runtime.CompilerServices.NullableAttribute' is not defined or imported // object this[object x, object? y] => throw new System.NotImplementedException(); Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "object? y").WithArguments("System.Runtime.CompilerServices.NullableAttribute").WithLocation(3, 27)); @@ -1295,7 +1312,14 @@ public void ModuleMissingAttribute_OperatorReturnType() comp.VerifyEmitDiagnostics( // (3,19): error CS0518: Predefined type 'System.Runtime.CompilerServices.NullableAttribute' is not defined or imported // public static object? operator+(C a, C b) => null; - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "object?").WithArguments("System.Runtime.CompilerServices.NullableAttribute").WithLocation(3, 19)); + Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "object?").WithArguments("System.Runtime.CompilerServices.NullableAttribute").WithLocation(3, 19), + // (3,37): error CS0518: Predefined type 'System.Runtime.CompilerServices.NullableAttribute' is not defined or imported + // public static object? operator+(C a, C b) => null; + Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "C a").WithArguments("System.Runtime.CompilerServices.NullableAttribute").WithLocation(3, 37), + // (3,42): error CS0518: Predefined type 'System.Runtime.CompilerServices.NullableAttribute' is not defined or imported + // public static object? operator+(C a, C b) => null; + Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "C b").WithArguments("System.Runtime.CompilerServices.NullableAttribute").WithLocation(3, 42) + ); } [Fact] @@ -1308,6 +1332,12 @@ public void ModuleMissingAttribute_OperatorParameters() }"; var comp = CreateCompilation(new[] { source }, parseOptions: TestOptions.Regular8, options: WithNonNullTypesTrue(TestOptions.ReleaseModule)); comp.VerifyEmitDiagnostics( + // (3,19): error CS0518: Predefined type 'System.Runtime.CompilerServices.NullableAttribute' is not defined or imported + // public static object operator+(C a, object?[] b) => a; + Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "object").WithArguments("System.Runtime.CompilerServices.NullableAttribute").WithLocation(3, 19), + // (3,36): error CS0518: Predefined type 'System.Runtime.CompilerServices.NullableAttribute' is not defined or imported + // public static object operator+(C a, object?[] b) => a; + Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "C a").WithArguments("System.Runtime.CompilerServices.NullableAttribute").WithLocation(3, 36), // (3,41): error CS0518: Predefined type 'System.Runtime.CompilerServices.NullableAttribute' is not defined or imported // public static object operator+(C a, object?[] b) => a; Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "object?[] b").WithArguments("System.Runtime.CompilerServices.NullableAttribute").WithLocation(3, 41)); @@ -1380,6 +1410,12 @@ static void G() }"; var comp = CreateCompilation(new[] { source }, parseOptions: TestOptions.Regular8, options: WithNonNullTypesTrue(TestOptions.ReleaseModule)); comp.VerifyEmitDiagnostics( + // (1,20): error CS0518: Predefined type 'System.Runtime.CompilerServices.NullableAttribute' is not defined or imported + // delegate void D(T t); + Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "T t").WithArguments("System.Runtime.CompilerServices.NullableAttribute").WithLocation(1, 20), + // (4,22): error CS0518: Predefined type 'System.Runtime.CompilerServices.NullableAttribute' is not defined or imported + // static void F(D d) + Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "D d").WithArguments("System.Runtime.CompilerServices.NullableAttribute").WithLocation(4, 22), // (9,12): error CS0518: Predefined type 'System.Runtime.CompilerServices.NullableAttribute' is not defined or imported // F((object? o) => { }); Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "object? o").WithArguments("System.Runtime.CompilerServices.NullableAttribute").WithLocation(9, 12)); @@ -1420,7 +1456,10 @@ void L(object? x, object y) { } comp.VerifyEmitDiagnostics( // (5,16): error CS0518: Predefined type 'System.Runtime.CompilerServices.NullableAttribute' is not defined or imported // void L(object? x, object y) { } - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "object? x").WithArguments("System.Runtime.CompilerServices.NullableAttribute").WithLocation(5, 16)); + Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "object? x").WithArguments("System.Runtime.CompilerServices.NullableAttribute").WithLocation(5, 16), + // (5,27): error CS0518: Predefined type 'System.Runtime.CompilerServices.NullableAttribute' is not defined or imported + // void L(object? x, object y) { } + Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "object y").WithArguments("System.Runtime.CompilerServices.NullableAttribute").WithLocation(5, 27)); } [Fact] @@ -1444,18 +1483,18 @@ public void Tuples() var customAttributes = field.GetCustomAttributes(); AssertAttributes(reader, customAttributes, "MemberReference:Void System.Runtime.CompilerServices.TupleElementNamesAttribute..ctor(String[])", - "MethodDefinition:Void System.Runtime.CompilerServices.NullableAttribute..ctor(Boolean[])"); + "MethodDefinition:Void System.Runtime.CompilerServices.NullableAttribute..ctor(Byte[])"); var customAttribute = reader.GetCustomAttribute(customAttributes.ElementAt(1)); - AssertEx.Equal(ImmutableArray.Create(false, false, true, false, true, false, false, false, false, true, false, true), reader.ReadBoolArray(customAttribute.Value)); + AssertEx.Equal(ImmutableArray.Create(0, 0, 2, 0, 2, 0, 0, 0, 0, 2, 0, 2), reader.ReadByteArray(customAttribute.Value)); // Long tuple field = fieldDefs.Single(f => reader.StringComparer.Equals(f.Name, "Long")); customAttributes = field.GetCustomAttributes(); AssertAttributes(reader, customAttributes, "MemberReference:Void System.Runtime.CompilerServices.TupleElementNamesAttribute..ctor(String[])", - "MethodDefinition:Void System.Runtime.CompilerServices.NullableAttribute..ctor(Boolean[])"); + "MethodDefinition:Void System.Runtime.CompilerServices.NullableAttribute..ctor(Byte[])"); customAttribute = reader.GetCustomAttribute(customAttributes.ElementAt(1)); - AssertEx.Equal(ImmutableArray.Create(false, true, false, true, false, true, false, true, false, false, true), reader.ReadBoolArray(customAttribute.Value)); + AssertEx.Equal(ImmutableArray.Create(0, 2, 0, 2, 0, 2, 0, 2, 0, 0, 2), reader.ReadByteArray(customAttribute.Value)); }); var source2 = @@ -1547,20 +1586,20 @@ public class B : var reader = assembly.GetMetadataReader(); var typeDef = GetTypeDefinitionByName(reader, "B`1"); // Base type - checkAttributesNoDynamic(typeDef.GetCustomAttributes(), addOne: true); // add one for A + checkAttributesNoDynamic(typeDef.GetCustomAttributes(), addOne: 0); // add one for A // Interface implementation var interfaceImpl = reader.GetInterfaceImplementation(typeDef.GetInterfaceImplementations().Single()); - checkAttributesNoDynamic(interfaceImpl.GetCustomAttributes(), addOne: true); // add one for I + checkAttributesNoDynamic(interfaceImpl.GetCustomAttributes(), addOne: 0); // add one for I // Type parameter constraint type var typeParameter = reader.GetGenericParameter(typeDef.GetGenericParameters()[0]); var constraint = reader.GetGenericParameterConstraint(typeParameter.GetConstraints()[0]); - checkAttributesNoDynamic(constraint.GetCustomAttributes(), addOne: true); // add one for A + checkAttributesNoDynamic(constraint.GetCustomAttributes(), addOne: 1); // add one for A // Field type var field = typeDef.GetFields().Select(f => reader.GetFieldDefinition(f)).Single(f => reader.StringComparer.Equals(f.Name, "Field")); checkAttributes(field.GetCustomAttributes()); // Event type var @event = typeDef.GetEvents().Select(e => reader.GetEventDefinition(e)).Single(e => reader.StringComparer.Equals(e.Name, "Event")); - checkAttributes(@event.GetCustomAttributes(), addOne: true); // add one for EventHandler + checkAttributes(@event.GetCustomAttributes(), addOne: 1); // add one for EventHandler // Method return type and parameter type var method = typeDef.GetMethods().Select(m => reader.GetMethodDefinition(m)).Single(m => reader.StringComparer.Equals(m.Name, "Method")); var parameters = method.GetParameters().Select(p => reader.GetParameter(p)).ToArray(); @@ -1570,32 +1609,31 @@ public class B : var property = typeDef.GetProperties().Select(p => reader.GetPropertyDefinition(p)).Single(p => reader.StringComparer.Equals(p.Name, "Property")); checkAttributes(property.GetCustomAttributes()); - void checkAttributes(CustomAttributeHandleCollection customAttributes, bool addOne = false) + void checkAttributes(CustomAttributeHandleCollection customAttributes, byte? addOne = null) { AssertAttributes(reader, customAttributes, "MemberReference:Void System.Runtime.CompilerServices.DynamicAttribute..ctor(Boolean[])", "MemberReference:Void System.Runtime.CompilerServices.TupleElementNamesAttribute..ctor(String[])", - "MethodDefinition:Void System.Runtime.CompilerServices.NullableAttribute..ctor(Boolean[])"); - checkAttribute(reader.GetCustomAttribute(customAttributes.ElementAt(0)), addOne); + "MethodDefinition:Void System.Runtime.CompilerServices.NullableAttribute..ctor(Byte[])"); checkAttribute(reader.GetCustomAttribute(customAttributes.ElementAt(2)), addOne); } - void checkAttributesNoDynamic(CustomAttributeHandleCollection customAttributes, bool addOne = false) + void checkAttributesNoDynamic(CustomAttributeHandleCollection customAttributes, byte? addOne = null) { AssertAttributes(reader, customAttributes, "MemberReference:Void System.Runtime.CompilerServices.TupleElementNamesAttribute..ctor(String[])", - "MethodDefinition:Void System.Runtime.CompilerServices.NullableAttribute..ctor(Boolean[])"); + "MethodDefinition:Void System.Runtime.CompilerServices.NullableAttribute..ctor(Byte[])"); checkAttribute(reader.GetCustomAttribute(customAttributes.ElementAt(1)), addOne); } - void checkAttribute(CustomAttribute customAttribute, bool addOne) + void checkAttribute(CustomAttribute customAttribute, byte? addOne) { - var expectedBits = ImmutableArray.Create(false, true, false, false, true, false, true, false, true, false, false, true); - if (addOne) + var expectedBits = ImmutableArray.Create(0, 2, 0, 1, 2, 1, 2, 1, 2, 1, 0, 2); + if (addOne.HasValue) { - expectedBits = ImmutableArray.Create(false).Concat(expectedBits); + expectedBits = ImmutableArray.Create(addOne.GetValueOrDefault()).Concat(expectedBits); } - AssertEx.Equal(expectedBits, reader.ReadBoolArray(customAttribute.Value)); + AssertEx.Equal(expectedBits, reader.ReadByteArray(customAttribute.Value)); } }); diff --git a/src/Compilers/CSharp/Test/Semantic/FlowAnalysis/StructTests.cs b/src/Compilers/CSharp/Test/Semantic/FlowAnalysis/StructTests.cs index cad22886fbb24..5a014d933eb03 100644 --- a/src/Compilers/CSharp/Test/Semantic/FlowAnalysis/StructTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/FlowAnalysis/StructTests.cs @@ -416,7 +416,9 @@ internal class C1 { public struct S { +#nullable disable public string data; +#nullable enable } } public struct Struct diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs index 320612803cfa4..1f21dda148a2d 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs @@ -1216,182 +1216,7 @@ class C4 { }"; } [Fact] - public void EmbeddedAttribute_Injected() - { - var source = @" -" + NonNullTypesOn() + @" -[module: Microsoft.CodeAnalysis.Embedded] - -[Microsoft.CodeAnalysis.Embedded] -public class C -{ - [Microsoft.CodeAnalysis.Embedded] - public int field = 0; - [Microsoft.CodeAnalysis.Embedded] - void M() { } -} -[Microsoft.CodeAnalysis.Embedded] -interface I { } -"; - var comp = CreateCompilation(source); - comp.VerifyEmitDiagnostics(); - - var type = (NamedTypeSymbol)comp.GlobalNamespace.GetMember("Microsoft.CodeAnalysis.EmbeddedAttribute"); - Assert.NotNull(type); - Assert.Equal(0, type.Arity); - Assert.Equal("System.Attribute", type.BaseTypeNoUseSiteDiagnostics.ToTestDisplayString()); - Assert.True(type.CanBeReferencedByName); - Assert.Equal("Microsoft.CodeAnalysis.EmbeddedAttribute..ctor()", type.Constructors.Single().ToTestDisplayString()); - Assert.Null(type.ContainingType); - Assert.Empty(type.DeclaringSyntaxReferences); - Assert.True(type.HasCodeAnalysisEmbeddedAttribute); - Assert.False(type.HasDeclarativeSecurity); - Assert.False(type.HasSpecialName); - Assert.False(type.HasUnsupportedMetadata); - Assert.Empty(type.Indexers); - Assert.Equal("Microsoft.CodeAnalysis.EmbeddedAttribute..ctor()", type.InstanceConstructors.Single().ToTestDisplayString()); - Assert.False(type.IsAbstract); - Assert.False(type.IsAnonymousType); - Assert.False(type.IsByRefLikeType); - Assert.False(type.IsComImport); - Assert.False(type.IsConditional); - Assert.True(type.IsDefinition); - Assert.False(type.IsExtern); - Assert.False(type.IsGenericType); - Assert.True(type.IsImplicitlyDeclared); - Assert.False(type.IsInterface); - Assert.False(type.IsManagedType); - Assert.False(type.IsNamespace); - Assert.True(type.IsReferenceType); - Assert.True(type.IsSealed); - Assert.False(type.IsSerializable); - Assert.False(type.IsStatic); - Assert.False(type.IsTupleType); - Assert.True(type.IsType); - Assert.Equal(SymbolKind.NamedType, type.Kind); - Assert.Equal("C#", type.Language); - Assert.Empty(type.Locations); - Assert.Equal(new[] { ".ctor" }, type.MemberNames); - Assert.False(type.MightContainExtensionMethods); - Assert.Equal("EmbeddedAttribute", type.Name); - Assert.Null(type.NonNullTypes); - Assert.Equal(SpecialType.None, type.SpecialType); - Assert.Empty(type.StaticConstructors); - Assert.Equal(TypeKind.Class, type.TypeKind); - - var codeAnalysis = type.ContainingNamespace; - verifyEmptyNamespace(codeAnalysis, "CodeAnalysis"); - - var microsoft = codeAnalysis.ContainingNamespace; - verifyEmptyNamespace(microsoft, "Microsoft"); - - Assert.True(microsoft.ContainingNamespace.IsGlobalNamespace); - - var type2 = comp.GetWellKnownType(WellKnownType.Microsoft_CodeAnalysis_EmbeddedAttribute); - Assert.True(type.Equals(type2)); - Assert.Equal(Accessibility.Internal, type.DeclaredAccessibility); - - void verifyEmptyNamespace(INamespaceSymbol symbol, string expectedName) - { - Assert.Equal(expectedName, symbol.Name); - Assert.Empty(symbol.DeclaringSyntaxReferences); - Assert.Empty(symbol.Locations); - Assert.True(symbol.IsImplicitlyDeclared); - Assert.Equal(NamespaceKind.Module, symbol.NamespaceKind); - } - } - - [Fact] - public void NonNullTypesAttribute_Injected_InCSharp7() - { - var comp = CreateCompilation("", options: WithNonNullTypesTrue(), parseOptions: TestOptions.Regular7); - comp.VerifyDiagnostics( - // error CS8630: Invalid 'Nullable' value: 'True' for C# 7.0. Please use language version 8.0 or greater. - Diagnostic(ErrorCode.ERR_NullableOptionNotAvailable).WithArguments("Nullable", "True", "7.0", "8.0").WithLocation(1, 1) - ); - - Assert.True(comp.SourceModule.NonNullTypes); - Assert.Empty(comp.SourceModule.GetAttributes()); - - var type = (NamedTypeSymbol)comp.GlobalNamespace.GetMember("System.Runtime.CompilerServices.NonNullTypesAttribute"); - Assert.NotNull(type); - Assert.Equal(0, type.Arity); - Assert.Equal("System.Attribute", type.BaseTypeNoUseSiteDiagnostics.ToTestDisplayString()); - Assert.True(type.CanBeReferencedByName); - Assert.Equal("System.Runtime.CompilerServices.NonNullTypesAttribute..ctor([System.Boolean flag = true])", type.Constructors.Single().ToTestDisplayString()); - Assert.Null(type.ContainingType); - Assert.Empty(type.DeclaringSyntaxReferences); - Assert.True(type.HasCodeAnalysisEmbeddedAttribute); - Assert.False(type.HasDeclarativeSecurity); - Assert.False(type.HasSpecialName); - Assert.False(type.HasUnsupportedMetadata); - Assert.Empty(type.Indexers); - Assert.Equal("System.Runtime.CompilerServices.NonNullTypesAttribute..ctor([System.Boolean flag = true])", type.InstanceConstructors.Single().ToTestDisplayString()); - Assert.False(type.IsAbstract); - Assert.False(type.IsAnonymousType); - Assert.False(type.IsByRefLikeType); - Assert.False(type.IsComImport); - Assert.False(type.IsConditional); - Assert.True(type.IsDefinition); - Assert.False(type.IsExtern); - Assert.False(type.IsGenericType); - Assert.True(type.IsImplicitlyDeclared); - Assert.False(type.IsInterface); - Assert.False(type.IsManagedType); - Assert.False(type.IsNamespace); - Assert.True(type.IsReferenceType); - Assert.True(type.IsSealed); - Assert.False(type.IsSerializable); - Assert.False(type.IsStatic); - Assert.False(type.IsTupleType); - Assert.True(type.IsType); - Assert.Equal(SymbolKind.NamedType, type.Kind); - Assert.Equal("C#", type.Language); - Assert.Empty(type.Locations); - Assert.Equal(new[] { ".ctor" }, type.MemberNames); - Assert.False(type.MightContainExtensionMethods); - Assert.Equal("NonNullTypesAttribute", type.Name); - Assert.True(type.NonNullTypes); - Assert.Equal(SpecialType.None, type.SpecialType); - Assert.Empty(type.StaticConstructors); - Assert.Equal(TypeKind.Class, type.TypeKind); - - var compilerServices = type.ContainingNamespace; - verifyEmptyNamespace(compilerServices, "CompilerServices"); - - var runtime = compilerServices.ContainingNamespace; - verifyEmptyNamespace(runtime, "Runtime"); - - var system = runtime.ContainingNamespace; - verifyEmptyNamespace(system, "System"); - - Assert.True(system.ContainingNamespace.IsGlobalNamespace); - - var type2 = comp.GetWellKnownType(WellKnownType.System_Runtime_CompilerServices_NonNullTypesAttribute); - Assert.True(type.Equals(type2)); - Assert.Equal(Accessibility.Internal, type.DeclaredAccessibility); - - // https://github.com/dotnet/roslyn/issues/29683 CSharpCompilation.AbstractSymbolSearcher needs to inject namespaces and types too - //Assert.True(comp.ContainsSymbolsWithName("NonNullTypesAttribute", SymbolFilter.Type)); - //Assert.Equal("System.Runtime.CompilerServices.NonNullTypesAttribute", comp.GetSymbolsWithName("NonNullTypesAttribute", SymbolFilter.Type).Single().ToTestDisplayString()); - //Assert.Equal("System.Runtime.CompilerServices.NonNullTypesAttribute", comp.GetSymbolsWithName(n => n == "NonNullTypesAttribute", SymbolFilter.Type).Single().ToTestDisplayString()); - - //Assert.True(comp.ContainsSymbolsWithName("EmbeddedAttribute", SymbolFilter.Type)); - //Assert.Equal("Microsoft.CodeAnalysis.EmbeddedAttribute", comp.GetSymbolsWithName("EmbeddedAttribute", SymbolFilter.Type).Single().ToTestDisplayString()); - //Assert.Equal("Microsoft.CodeAnalysis.EmbeddedAttribute", comp.GetSymbolsWithName(n => n == "EmbeddedAttribute", SymbolFilter.Type).Single().ToTestDisplayString()); - - void verifyEmptyNamespace(INamespaceSymbol symbol, string expectedName) - { - Assert.Equal(expectedName, symbol.Name); - Assert.Empty(symbol.DeclaringSyntaxReferences); - Assert.Empty(symbol.Locations); - Assert.True(symbol.IsImplicitlyDeclared); - Assert.Equal(NamespaceKind.Module, symbol.NamespaceKind); - } - } - - [Fact] - public void NonNullTypesAttribute_False_Injected_InCSharp7() + public void Nullable_False_InCSharp7() { var comp = CreateCompilation("", options: WithNonNullTypesFalse(), parseOptions: TestOptions.Regular7); comp.VerifyDiagnostics( @@ -1400,9 +1225,6 @@ public void NonNullTypesAttribute_False_Injected_InCSharp7() ); Assert.False(comp.SourceModule.NonNullTypes); - - var type = (NamedTypeSymbol)comp.GlobalNamespace.GetMember("System.Runtime.CompilerServices.NonNullTypesAttribute"); - Assert.False(type.NonNullTypes); } [Fact] @@ -1424,518 +1246,6 @@ public void NullableOption() comp.VerifyDiagnostics(); } - [Fact] - public void NonNullTypesAttributeInMergedNamespaceSymbol() - { - var reference_cs = @" -namespace System.Runtime.CompilerServices -{ - public sealed class NonNullTypesAttribute : Attribute - { - public NonNullTypesAttribute(bool enabled = true) { } - } -}"; - var reference = CreateCompilation(new[] { reference_cs }); - reference.VerifyDiagnostics(); - - var comp_cs = @" -namespace System.Runtime.CompilerServices.NonNullTypesAttribute -{ - class C { } -}"; - var comp = CreateCompilation(new[] { comp_cs }, options: WithNonNullTypesTrue(), references: new[] { reference.ToMetadataReference() }); - // https://github.com/dotnet/roslyn/issues/30583: Report an error if we are unable to synthesize NonNullTypesAttribute application - comp.VerifyEmitDiagnostics( - //// (1,42): error CS0616: 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not an attribute class - //// [module: System.Runtime.CompilerServices.NonNullTypes(true)] - //Diagnostic(ErrorCode.ERR_NotAnAttributeClass, "NonNullTypes").WithArguments("System.Runtime.CompilerServices.NonNullTypesAttribute").WithLocation(1, 42) - ); - - var type = comp.GetWellKnownType(WellKnownType.System_Runtime_CompilerServices_NonNullTypesAttribute); - Assert.True(type.IsErrorType()); - - // https://github.com/dotnet/roslyn/issues/29683 CSharpCompilation.AbstractSymbolSearcher needs to inject namespaces and types too - //Assert.False(comp.ContainsSymbolsWithName("NonNullTypesAttribute", SymbolFilter.Type)); - //Assert.Empty(comp.GetSymbolsWithName("NonNullTypesAttribute", SymbolFilter.Type)); - //Assert.Empty(comp.GetSymbolsWithName(n => n == "NonNullTypesAttribute", SymbolFilter.Type)); - - //Assert.True(comp.ContainsSymbolsWithName("EmbeddedAttribute", SymbolFilter.Type)); - //Assert.Equal("Microsoft.CodeAnalysis.EmbeddedAttribute", comp.GetSymbolsWithName("EmbeddedAttribute", SymbolFilter.Type).Single().ToTestDisplayString()); - //Assert.Equal("Microsoft.CodeAnalysis.EmbeddedAttribute", comp.GetSymbolsWithName(n => n == "EmbeddedAttribute", SymbolFilter.Type).Single().ToTestDisplayString()); - } - - [Fact] - public void NonNullTypesAttribute_NotInjectedIntoWrongNamespace() - { - var source = @" -namespace NotRoot.System { } -namespace NotSystem.Runtime { } -namespace NotRuntime.CompilerServices { } -"; - var comp = CreateCompilation(source); - Assert.Empty(((NamespaceSymbol)comp.SourceModule.GlobalNamespace.GetMember("NotRoot.System")).GetMembers()); - Assert.Empty(((NamespaceSymbol)comp.SourceModule.GlobalNamespace.GetMember("NotSystem.Runtime")).GetMembers()); - Assert.Empty(((NamespaceSymbol)comp.SourceModule.GlobalNamespace.GetMember("NotRuntime.CompilerServices")).GetMembers()); - Assert.Equal("System.Runtime.CompilerServices.NonNullTypesAttribute", - ((NamespaceSymbol)comp.SourceModule.GlobalNamespace.GetMember("System.Runtime.CompilerServices")).GetMembers().Single().ToTestDisplayString()); - } - - [Fact] - public void EmbeddedAttribute_NotInjectedIntoWrongNamespace() - { - var source = @" -namespace NotRoot.Microsoft { } -namespace NotMicrosoft.CodeAnalysis { } -"; - var comp = CreateCompilation(source); - Assert.Empty(((NamespaceSymbol)comp.SourceModule.GlobalNamespace.GetMember("NotRoot.Microsoft")).GetMembers()); - Assert.Empty(((NamespaceSymbol)comp.SourceModule.GlobalNamespace.GetMember("NotMicrosoft.CodeAnalysis")).GetMembers()); - Assert.Equal("Microsoft.CodeAnalysis.EmbeddedAttribute", - ((NamespaceSymbol)comp.SourceModule.GlobalNamespace.GetMember("Microsoft.CodeAnalysis")).GetMembers().Single().ToTestDisplayString()); - } - - // https://github.com/dotnet/roslyn/issues/30144: - // Test emitting netmodule (we won't inject NNT) - // Test script - - [Fact] - public void NonNullTypesAttribute_Injected() - { - NonNullTypesAttribute_Injected("", WithNonNullTypesTrue()); - NonNullTypesAttribute_Injected("", WithNonNullTypesFalse()); - NonNullTypesAttribute_Injected( -NonNullTypesOn() + @" -class C { }"); - NonNullTypesAttribute_Injected( -@"class C { -" + NonNullTypesOn() + @" -public string s = null!; }"); - NonNullTypesAttribute_Injected( -@"class C { -" + NonNullTypesOn() + @" -public event System.Action e; void M() { e(); } }"); - NonNullTypesAttribute_Injected( -@"class C { -" + NonNullTypesOn() + @" -void M() { } }"); - NonNullTypesAttribute_Injected( -@"class C { -" + NonNullTypesOn() + @" -string P { get; set; } }"); - NonNullTypesAttribute_Injected("using System.Runtime.CompilerServices; class C { NonNullTypesAttribute M() => throw null; }"); - NonNullTypesAttribute_Injected("using System.Runtime.CompilerServices; class C { void M(NonNullTypesAttribute x) => throw null; }"); - NonNullTypesAttribute_Injected("using System.Runtime.CompilerServices; namespace System { class C { void M(NonNullTypesAttribute x) => throw null; } }"); - NonNullTypesAttribute_Injected("using System.Runtime.CompilerServices; namespace System.Runtime { class C { void M(NonNullTypesAttribute x) => throw null; } }"); - NonNullTypesAttribute_Injected("namespace System.Runtime.CompilerServices { class C { void M(NonNullTypesAttribute x) => throw null; } }"); - NonNullTypesAttribute_Injected("using System.Runtime.CompilerServices; class C { NonNullTypesAttribute field = null; void M() { if (field != null) field = null; } }"); - NonNullTypesAttribute_Injected("using System.Runtime.CompilerServices; class C { void M() { _ = new NonNullTypesAttribute(); } }"); - NonNullTypesAttribute_Injected("using System.Runtime.CompilerServices; class C { void M() { local(); void local() { _ = new NonNullTypesAttribute(); } } }"); - } - - private void NonNullTypesAttribute_Injected(string source, CSharpCompilationOptions options = null) - { - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular8, options: options); - comp.VerifyDiagnostics(); - - Action validator = module => - { - var nonNullTypesAttribute = (NamedTypeSymbol)module.GlobalNamespace.GetMember("System.Runtime.CompilerServices.NonNullTypesAttribute"); - Assert.NotNull(nonNullTypesAttribute); - Assert.Equal(Accessibility.Internal, nonNullTypesAttribute.DeclaredAccessibility); - Assert.True(nonNullTypesAttribute.IsSealed); - Assert.Equal(SymbolKind.NamedType, nonNullTypesAttribute.Kind); - - var embeddedAttribute = module.GlobalNamespace.GetMember("Microsoft.CodeAnalysis.EmbeddedAttribute"); - Assert.NotNull(embeddedAttribute); - - var actualNonNullTypes = nonNullTypesAttribute.GetAttributes().Select(a => a.ToString()).ToArray(); - var actualEmbedded = embeddedAttribute.GetAttributes().Select(a => a.ToString()).ToArray(); - - // https://github.com/dotnet/roslyn/issues/29672 AttributeData.ToString() prints out a different order on CoreCLR - if (ExecutionConditionUtil.IsDesktop) - { - if (module is PEModuleSymbol) - { - Assert.Equal(new[] { - "System.Runtime.CompilerServices.CompilerGeneratedAttribute", - "Microsoft.CodeAnalysis.EmbeddedAttribute", - "System.AttributeUsageAttribute(System.AttributeTargets.Module | System.AttributeTargets.Class | System.AttributeTargets.Struct | System.AttributeTargets.Enum | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Property | System.AttributeTargets.Field | System.AttributeTargets.Event | System.AttributeTargets.Interface | System.AttributeTargets.Delegate)" }, - actualNonNullTypes); - Assert.Equal(new[] { - "System.Runtime.CompilerServices.CompilerGeneratedAttribute", - "Microsoft.CodeAnalysis.EmbeddedAttribute" }, - actualEmbedded); - } - else - { - Assert.Equal(new[] { - "System.AttributeUsageAttribute(System.AttributeTargets.Module | System.AttributeTargets.Class | System.AttributeTargets.Struct | System.AttributeTargets.Enum | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Property | System.AttributeTargets.Field | System.AttributeTargets.Event | System.AttributeTargets.Interface | System.AttributeTargets.Delegate)" }, - actualNonNullTypes); - Assert.Empty(actualEmbedded); - } - } - }; - - CompileAndVerify(comp, sourceSymbolValidator: validator, symbolValidator: validator); - } - - [Fact] - public void NonNullTypesAttribute_Injected_WithAmbiguousUserDefinedType() - { - var source = @" -using System.Runtime.CompilerServices; -using N1; - -[module: NonNullTypesAttribute(true)] -namespace N1 -{ - public class NonNullTypesAttribute : System.Attribute - { - public NonNullTypesAttribute(bool flag) => throw null; - } -} -"; - var comp = CreateCompilation(source); - comp.VerifyDiagnostics( - // (5,10): error CS0104: 'NonNullTypesAttribute' is an ambiguous reference between 'N1.NonNullTypesAttribute' and 'System.Runtime.CompilerServices.NonNullTypesAttribute' - // [module: NonNullTypesAttribute(true)] - Diagnostic(ErrorCode.ERR_AmbigContext, "NonNullTypesAttribute").WithArguments("NonNullTypesAttribute", "N1.NonNullTypesAttribute", "System.Runtime.CompilerServices.NonNullTypesAttribute").WithLocation(5, 10) - ); - } - - [Fact] - public void NonNullTypesAttribute_Injected_WithNonAmbiguousUserDefinedType() - { - var source = @" -using N1; -[module: NonNullTypesAttribute(true)] -namespace N1 -{ - public class NonNullTypesAttribute : System.Attribute - { - public NonNullTypesAttribute(bool flag) => throw null; - } -} -"; - var comp = CreateCompilation(source); - comp.VerifyDiagnostics(); - } - - [Fact] - public void NonNullTypesAttribute_WithoutUsage() - { - var comp = CreateCompilation("class C { }", parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics(); - - Action sourceValidator = module => - { - var nonNullTypes = (NamedTypeSymbol)module.GlobalNamespace.GetMember("System.Runtime.CompilerServices.NonNullTypesAttribute"); - Assert.NotNull(nonNullTypes); - var embedded = (NamedTypeSymbol)module.GlobalNamespace.GetMember("Microsoft.CodeAnalysis.EmbeddedAttribute"); - Assert.NotNull(embedded); - - var system = (INamespaceSymbol)module.GlobalNamespace.GetMember("System"); - Assert.Equal(NamespaceKind.Module, system.NamespaceKind); - }; - - Action peValidator = module => - { - var nonNullTypes = (NamedTypeSymbol)module.GlobalNamespace.GetMember("System.Runtime.CompilerServices.NonNullTypesAttribute"); - Assert.Null(nonNullTypes); - var embedded = (NamedTypeSymbol)module.GlobalNamespace.GetMember("Microsoft.CodeAnalysis.EmbeddedAttribute"); - Assert.Null(embedded); - - var system = (INamespaceSymbol)module.GlobalNamespace.GetMember("System"); - Assert.Null(system); - }; - CompileAndVerify(comp, sourceSymbolValidator: sourceValidator, symbolValidator: peValidator, verify: Verification.Skipped); - } - - [Fact] - public void NonNullTypesAttribute_WithoutAttribute() - { - var source = @" -namespace System -{ - public class Object { } - public struct Void { } - // missing Attribute - public class ValueType { } - public struct Boolean { } - public class String { } -} -"; - var comp = CreateEmptyCompilation(new[] { source }, options: WithNonNullTypesTrue()); - comp.VerifyDiagnostics(); - comp.VerifyEmitDiagnostics(CodeAnalysis.Emit.EmitOptions.Default.WithRuntimeMetadataVersion("v4.0.30319"), - // error CS0518: Predefined type 'System.Attribute' is not defined or imported - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Attribute").WithLocation(1, 1), - // error CS0656: Missing compiler required member 'System.AttributeUsageAttribute..ctor' - Diagnostic(ErrorCode.ERR_MissingPredefinedMember).WithArguments("System.AttributeUsageAttribute", ".ctor").WithLocation(1, 1), - // error CS0518: Predefined type 'System.Attribute' is not defined or imported - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Attribute").WithLocation(1, 1), - // error CS0518: Predefined type 'System.Attribute' is not defined or imported - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Attribute").WithLocation(1, 1) - ); - } - - [Fact] - public void NonNullTypesAttribute_WithoutAttributeUsage() - { - var source = @" -namespace System -{ - public class Object { } - public struct Void { } - public class Attribute { } - public class ValueType { } - public struct Boolean { } - public class String { } - // missing AttributeUsageAttribute -} -"; - var comp = CreateEmptyCompilation(new[] { source }, options: WithNonNullTypesTrue()); - comp.VerifyEmitDiagnostics(CodeAnalysis.Emit.EmitOptions.Default.WithRuntimeMetadataVersion("v4.0.30319"), - // error CS0656: Missing compiler required member 'System.AttributeUsageAttribute..ctor' - Diagnostic(ErrorCode.ERR_MissingPredefinedMember).WithArguments("System.AttributeUsageAttribute", ".ctor").WithLocation(1, 1) - ); - } - - [Fact] - public void EmbeddedAttribute_WithoutAttribute() - { - var source = @" -namespace System -{ - public class Object { } - public struct Void { } - // missing Attribute - public class ValueType { } - public struct Boolean { } - public class String { } - public struct Int32 { } - public class Enum { } -} -namespace System.Runtime.InteropServices -{ - public enum UnmanagedType { } -} -class C where T : unmanaged -{ -} -"; - var comp = CreateEmptyCompilation(source); - comp.VerifyEmitDiagnostics(CodeAnalysis.Emit.EmitOptions.Default.WithRuntimeMetadataVersion("v4.0.30319"), - // error CS0518: Predefined type 'System.Attribute' is not defined or imported - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Attribute").WithLocation(1, 1) - ); - } - - [Fact] - public void EmbeddedAttribute_WithoutAttributeUsage() - { - var source = @" -namespace System -{ - public class Object { } - public struct Void { } - public class Attribute { } - public class ValueType { } - public struct Boolean { } - public class String { } - public struct Int32 { } - public class Enum { } - // missing AttributeUsage -} -namespace System.Runtime.InteropServices -{ - public enum UnmanagedType { } -} -class C where T : unmanaged -{ -} -"; - var comp = CreateEmptyCompilation(source); - comp.VerifyEmitDiagnostics(CodeAnalysis.Emit.EmitOptions.Default.WithRuntimeMetadataVersion("v4.0.30319")); - } - - [Fact] - public void NonNullTypesAttribute_WithoutAttributeUsageConstructor() - { - var source = @" -namespace System -{ - public class Object { } - public struct Void { } - public class Attribute { } - public class ValueType { } - public struct Boolean { } - public class String { } - public class AttributeUsageAttribute : Attribute { /* missing ctor */ } -} -"; - var comp = CreateEmptyCompilation(new[] { source }, options: WithNonNullTypesTrue()); - comp.VerifyEmitDiagnostics(CodeAnalysis.Emit.EmitOptions.Default.WithRuntimeMetadataVersion("v4.0.30319"), - // error CS0656: Missing compiler required member 'System.AttributeUsageAttribute..ctor' - Diagnostic(ErrorCode.ERR_MissingPredefinedMember).WithArguments("System.AttributeUsageAttribute", ".ctor").WithLocation(1, 1) - ); - } - - [Fact] - public void NonNullTypesAttribute_WithObsoleteAttributeUsageConstructor() - { - var source = @" -namespace System -{ - public class Object { } - public struct Void { } - public class Attribute { } - public class ValueType { } - public struct Boolean { } - public class String { } - public class Enum { } - public struct Int32 { } - public class AttributeUsageAttribute : Attribute - { - [System.Obsolete(""obsolete"")] - public AttributeUsageAttribute(AttributeTargets validOn) => throw null; - public bool AllowMultiple { get; set; } - } - public enum AttributeTargets { Assembly = 1, Module = 2, Class = 4, Struct = 8, - Enum = 16, Constructor = 32, Method = 64, Property = 128, Field = 256, - Event = 512, Interface = 1024, Parameter = 2048, Delegate = 4096, ReturnValue = 8192, - GenericParameter = 16384, All = 32767 } - public class ObsoleteAttribute : Attribute - { - public ObsoleteAttribute(string message) => throw null; - } -} -"; - var comp = CreateEmptyCompilation(new[] { source }, options: WithNonNullTypesTrue()); - comp.VerifyEmitDiagnostics(CodeAnalysis.Emit.EmitOptions.Default.WithRuntimeMetadataVersion("v4.0.30319")); - } - - [Fact] - public void NonNullTypesAttribute_WithBadAttributeConstructor() - { - var source = @" -namespace System -{ - public class Object { } - public struct Void { } - public class Attribute { public Attribute(bool ignored) { } } - public class ValueType { } - public struct Boolean { } - public class String { } - public class Enum { } - public struct Int32 { } - public class AttributeUsageAttribute : Attribute - { - public AttributeUsageAttribute(AttributeTargets validOn) : base(true) => throw null; - public bool AllowMultiple { get; set; } - } - public enum AttributeTargets { Assembly = 1, Module = 2, Class = 4, Struct = 8, - Enum = 16, Constructor = 32, Method = 64, Property = 128, Field = 256, - Event = 512, Interface = 1024, Parameter = 2048, Delegate = 4096, ReturnValue = 8192, - GenericParameter = 16384, All = 32767 } -} -"; - var comp = CreateEmptyCompilation(new[] { source }, options: WithNonNullTypesTrue()); - comp.VerifyEmitDiagnostics(CodeAnalysis.Emit.EmitOptions.Default.WithRuntimeMetadataVersion("v4.0.30319"), - // 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 - Diagnostic(ErrorCode.ERR_BadCtorArgCount).WithArguments("System.Attribute", "0").WithLocation(1, 1)); - - // https://github.com/dotnet/roslyn/issues/29732 We should not accumulate diagnostics with every attempt to emit - comp.VerifyEmitDiagnostics(CodeAnalysis.Emit.EmitOptions.Default.WithRuntimeMetadataVersion("v4.0.30319"), - // 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 - Diagnostic(ErrorCode.ERR_BadCtorArgCount).WithArguments("System.Attribute", "0").WithLocation(1, 1), - // 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 - Diagnostic(ErrorCode.ERR_BadCtorArgCount).WithArguments("System.Attribute", "0").WithLocation(1, 1)); - } - - [Fact] - public void NonNullTypesAttribute_WithAttributeUsage() - { - var source = @" -namespace System -{ - public class Object { } - public struct Void { } - public class Attribute { } - public class ValueType { } - public struct Boolean { } - public class String { } - public class Enum { } - public struct Int32 { } - public class AttributeUsageAttribute : Attribute - { - public AttributeUsageAttribute(AttributeTargets validOn) => throw null; - public bool AllowMultiple { get; set; } - } - public enum AttributeTargets { Assembly = 1, Module = 2, Class = 4, Struct = 8, - Enum = 16, Constructor = 32, Method = 64, Property = 128, Field = 256, - Event = 512, Interface = 1024, Parameter = 2048, Delegate = 4096, ReturnValue = 8192, - GenericParameter = 16384, All = 32767 } -} -"; - var comp = CreateEmptyCompilation(source); - comp.VerifyDiagnostics(); - } - - [Fact] - public void NonNullTypesAttribute_WithoutBool() - { - var source = @" -namespace System -{ - public class Object { } - public struct Void { } - public class Attribute { } - public class ValueType { } - public class String { } -} -"; - var comp = CreateEmptyCompilation(new[] { source }, options: WithNonNullTypesTrue()); - comp.VerifyEmitDiagnostics(CodeAnalysis.Emit.EmitOptions.Default.WithRuntimeMetadataVersion("v4.0.30319"), - // error CS0518: Predefined type 'System.Boolean' is not defined or imported - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Boolean").WithLocation(1, 1), - // error CS0518: Predefined type 'System.Boolean' is not defined or imported - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Boolean").WithLocation(1, 1), - // error CS0656: Missing compiler required member 'System.AttributeUsageAttribute..ctor' - Diagnostic(ErrorCode.ERR_MissingPredefinedMember).WithArguments("System.AttributeUsageAttribute", ".ctor").WithLocation(1, 1) - ); - } - - [Fact] - public void NonNullTypesAttribute_AlreadyDefined() - { - var corlib_cs = @" -namespace System -{ - public struct Boolean { } - public struct Void { } - public abstract class ValueType { } - public class Object { } - public class Attribute { } -} -namespace System.Runtime.CompilerServices -{ - public sealed class NonNullTypesAttribute : Attribute - { - public NonNullTypesAttribute(bool flag = true) { } - } -} -"; - var corlib = CreateEmptyCompilation(corlib_cs, parseOptions: TestOptions.Regular8); - corlib.VerifyDiagnostics(); - } - [Fact] public void NullableAttribute_NotRequiredCSharp7_01() { @@ -2136,6 +1446,7 @@ public class String public String? Concat(String a, String b) => throw null; } public class Enum { } + public struct Byte { } public struct Int32 { } public class AttributeUsageAttribute : Attribute { @@ -2806,67 +2117,6 @@ static void Main() comp1.VerifyDiagnostics(); } - [Fact] - public void NonNullTypes_False_Circular() - { - string source = @" -namespace System.Runtime.CompilerServices -{ - [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] -" + NonNullTypesOff() + @" - class NonNullTypesAttribute : Attribute - { - public NonNullTypesAttribute(bool flag = true) { } - } -} -"; - var comp = CreateCompilation(new[] { source }); - comp.VerifyDiagnostics(); - - VerifyNonNullTypes(comp.GetMember("System.Runtime.CompilerServices.NonNullTypesAttribute"), false); - } - - [Fact] - public void NonNullTypes_True_Circular() - { - string source = @" -namespace System.Runtime.CompilerServices -{ - [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] -" + NonNullTypesOn() + @" - class NonNullTypesAttribute : System.Attribute - { - public NonNullTypesAttribute(bool flag = true) { } - } -} -"; - var comp = CreateCompilation(new[] { source }); - comp.VerifyEmitDiagnostics(); - - VerifyNonNullTypes(comp.GetMember("System.Runtime.CompilerServices.NonNullTypesAttribute"), true); - } - - [Fact] - public void NonNullTypes_WithObsolete() - { - string source = @" -namespace System.Runtime.CompilerServices -{ - [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] -" + NonNullTypesOn() + @" - [System.Obsolete(""obsolete"")] - class NonNullTypesAttribute : System.Attribute - { - public NonNullTypesAttribute(bool flag = true) { } - } -} -"; - // We don't check whether well-known types are obsolete - var comp = CreateCompilation(new[] { source }); - comp.VerifyEmitDiagnostics(); - Assert.False(comp.GetMember("System.Runtime.CompilerServices.NonNullTypesAttribute").IsImplicitlyDeclared); - } - [Fact] public void Embedded_WithObsolete() { @@ -2971,65 +2221,6 @@ class AttributeWithProperty : System.ComponentModel.DisplayNameAttribute comp.VerifyDiagnostics(); } - [Fact] - public void NonNullTypes_OnSystemBoolean() - { - string source = @" -namespace System -{ -" + NonNullTypesOn() + @" - public struct Boolean { } -" + NonNullTypesOff() + @" - public class Attribute { } - public class Object { } - public struct Void { } - public class ValueType { } - public class Enum { } - public struct Int32 { } - public class AttributeUsageAttribute : Attribute - { - public AttributeUsageAttribute(AttributeTargets validOn) => throw null; - public bool AllowMultiple { get; set; } - } - public enum AttributeTargets { Assembly = 1, Module = 2, Class = 4, Struct = 8, - Enum = 16, Constructor = 32, Method = 64, Property = 128, Field = 256, - Event = 512, Interface = 1024, Parameter = 2048, Delegate = 4096, ReturnValue = 8192, - GenericParameter = 16384, All = 32767 } -} -namespace System.Runtime.CompilerServices -{ - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false)] - class NonNullTypesAttribute : Attribute - { - public NonNullTypesAttribute(bool flag = true) { } - } -} -"; - var comp = CreateEmptyCompilation(source); - comp.VerifyDiagnostics(); - } - - [WorkItem(29594, "https://github.com/dotnet/roslyn/issues/29594")] - [Fact(Skip = "Stack overflow")] - public void NonNullTypes_DoNotWarnInsideAttributes() - { - string source = @" -using System.Runtime.CompilerServices; -[NonNullTypes(true)] -class C -{ - [System.Obsolete(D.M1(D.M2()))] - class D - { - static void M1(string x) => throw null; - static string? M2() => throw null; - } -} -"; - var comp = CreateCompilation(source); - comp.VerifyDiagnostics(); - } - [Fact] public void NonNullTypes_OnFields() { @@ -3171,8 +2362,6 @@ public void M() Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(73, 36) ); - verifyExternal(compilation); - var outerA = (NamedTypeSymbol)compilation.GetMember("OuterA"); Assert.False(outerA.NonNullTypes); @@ -3681,8 +2870,6 @@ public void M() Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(57, 36) ); - verifyOblivious(compilation); - var outerA = (NamedTypeSymbol)compilation.GetMember("OuterA"); Assert.False(outerA.NonNullTypes); @@ -3704,11 +2891,6 @@ public void M() Assert.True(oblivious2.NonNullTypes); VerifyNonNullTypes(oblivious2.GetMember("s"), false); VerifyNonNullTypes(oblivious2.GetMember("ns"), false); - - void verifyOblivious(Compilation comp) - { - VerifyNonNullTypes(comp.GetMember("Oblivious"), null); - } } /// @@ -3756,7 +2938,14 @@ private static void VerifyNonNullTypes(MethodSymbol method, bool? expectNonNullT if (method.ReturnType.NullableAnnotation != NullableAnnotation.Nullable) { - Assert.Equal(expectNonNullTypes == true, method.ReturnType.NullableAnnotation != NullableAnnotation.Unknown); + if (method is SynthesizedInstanceConstructor) + { + Assert.Equal(NullableAnnotation.Unknown, method.ReturnType.NullableAnnotation); + } + else + { + Assert.Equal(expectNonNullTypes == true, method.ReturnType.NullableAnnotation != NullableAnnotation.Unknown); + } } foreach (var parameter in method.Parameters) @@ -3877,9 +3066,6 @@ public void M() Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(56, 25) ); - verifyOblivious(compilation); - verifyExternal(compilation); - var outerA = (NamedTypeSymbol)compilation.GetMember("OuterA"); Assert.False(outerA.NonNullTypes); @@ -3900,11 +3086,6 @@ public void M() var oblivious2 = (NamedTypeSymbol)compilation.GetMember("Oblivious2"); VerifyNonNullTypes(oblivious2, false); - void verifyOblivious(Compilation comp) - { - VerifyNonNullTypes((NamedTypeSymbol)comp.GetMember("Oblivious"), null); - } - void verifyExternal(Compilation comp) { VerifyNonNullTypes((NamedTypeSymbol)comp.GetMember("External"), true); @@ -3926,77 +3107,6 @@ public class Oblivious { } var compilation = CreateCompilation("", options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular8, references: new[] { obliviousComp.EmitToImageReference() }); compilation.VerifyDiagnostics(); - VerifyNonNullTypes(compilation.GetMember("Oblivious"), false); - } - - [Fact] - public void NonNullTypes_OnModule_WithExtraConstructor() - { - var obliviousLib = @" -public class Oblivious { } - -namespace System.Runtime.CompilerServices -{ - [AttributeUsage(AttributeTargets.All)] - public sealed class NonNullTypesAttribute : Attribute - { - public NonNullTypesAttribute(bool flag = true) { } - public NonNullTypesAttribute(string x) { } - } -} -"; - - var obliviousComp = CreateCompilation(obliviousLib, options: WithNonNullTypesFalse()); - obliviousComp.VerifyDiagnostics(); - VerifyNonNullTypes(obliviousComp.GetMember("Oblivious"), expectNonNullTypes: false); - - var compilation = CreateCompilation("", options: TestOptions.ReleaseDll, - parseOptions: TestOptions.Regular8, references: new[] { obliviousComp.EmitToImageReference() }); - compilation.VerifyDiagnostics(); - VerifyNonNullTypes(compilation.GetMember("Oblivious"), expectNonNullTypes: false); - } - - [Fact] - public void NonNullTypes_OnModule_WithAlias() - { - var obliviousLib = @" -using NonNullTypesAlias = System.Runtime.CompilerServices.NonNullTypesAttribute; - -" + NonNullTypesOff() + @" -public class Oblivious { } -"; - - var obliviousComp = CreateCompilation(new[] { obliviousLib }); - obliviousComp.VerifyDiagnostics( - // (2,1): hidden CS8019: Unnecessary using directive. - // using NonNullTypesAlias = System.Runtime.CompilerServices.NonNullTypesAttribute; - Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using NonNullTypesAlias = System.Runtime.CompilerServices.NonNullTypesAttribute;").WithLocation(2, 1) - ); - VerifyNonNullTypes(obliviousComp.GetMember("Oblivious"), expectNonNullTypes: false); - - var compilation = CreateCompilation("", options: TestOptions.ReleaseDll, - parseOptions: TestOptions.Regular8, references: new[] { obliviousComp.EmitToImageReference() }); - compilation.VerifyDiagnostics(); - VerifyNonNullTypes(compilation.GetMember("Oblivious"), expectNonNullTypes: false); - } - - [Fact] - public void NonNullTypes_OnAssembly() - { - var obliviousLib = @" -using System.Runtime.CompilerServices; - -[assembly: NonNullTypes(false)] -public class Oblivious { } -"; - - var obliviousComp = CreateCompilation(new[] { obliviousLib }, options: WithNonNullTypesTrue()); - obliviousComp.VerifyDiagnostics( - // (4,12): error CS0592: Attribute 'NonNullTypes' is not valid on this declaration type. It is only valid on 'module, class, struct, enum, constructor, method, property, indexer, field, event, interface, delegate' declarations. - // [assembly: NonNullTypes(false)] - Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "NonNullTypes").WithArguments("NonNullTypes", "module, class, struct, enum, constructor, method, property, indexer, field, event, interface, delegate").WithLocation(4, 12) - ); - VerifyNonNullTypes(obliviousComp.GetMember("Oblivious"), true); // The attribute is on assembly } [Fact] @@ -6031,14 +5141,14 @@ void Dummy() public void Overriding_Methods() { var source = @" -using System.Runtime.CompilerServices; + public abstract class A { " + NonNullTypesOff() + @" public abstract System.Action Oblivious1(System.Action x); " + NonNullTypesOn() + @" - [return: NonNullTypes(false)] - public abstract System.Action Oblivious2([NonNullTypes(false)] System.Action x); + + public abstract System.Action Oblivious2(System.Action x); public abstract System.Action M3(System.Action x); public abstract System.Action M4(System.Action x); public abstract System.Action? M5(System.Action? x); @@ -6055,14 +5165,14 @@ public class B1 : A public class B2 : A { - [return: NonNullTypes(false)] - public override System.Action Oblivious1([NonNullTypes(false)] System.Action x) => throw null; + + public override System.Action Oblivious1(System.Action x) => throw null; public override System.Action Oblivious2(System.Action x) => throw null; " + NonNullTypesOff() + @" public override System.Action M3(System.Action x) => throw null; " + NonNullTypesOn() + @" - [return: NonNullTypes(false)] - public override System.Action M4([NonNullTypes(false)] System.Action x) => throw null; + + public override System.Action M4(System.Action x) => throw null; " + NonNullTypesOff() + @" public override System.Action M5(System.Action x) => throw null; } @@ -6070,12 +5180,6 @@ public class B2 : A var compilation = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue()); compilation.VerifyDiagnostics( - // (8,14): error CS0592: Attribute 'NonNullTypes' is not valid on this declaration type. It is only valid on 'module, class, struct, enum, constructor, method, property, indexer, field, event, interface, delegate' declarations. - // [return: NonNullTypes(false)] - Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "NonNullTypes").WithArguments("NonNullTypes", "module, class, struct, enum, constructor, method, property, indexer, field, event, interface, delegate").WithLocation(8, 14), - // (9,55): error CS0592: Attribute 'NonNullTypes' is not valid on this declaration type. It is only valid on 'module, class, struct, enum, constructor, method, property, indexer, field, event, interface, delegate' declarations. - // public abstract System.Action Oblivious2([NonNullTypes(false)] System.Action x); - Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "NonNullTypes").WithArguments("NonNullTypes", "module, class, struct, enum, constructor, method, property, indexer, field, event, interface, delegate").WithLocation(9, 55), // (18,44): warning CS8609: Nullability of reference types in return type doesn't match overridden member. // public override System.Action Oblivious2(System.Action x) => throw null; // warn 3 and 4 // https://github.com/dotnet/roslyn/issues/29851: Should not warn Diagnostic(ErrorCode.WRN_NullabilityMismatchInReturnTypeOnOverride, "Oblivious2").WithLocation(18, 44), @@ -6099,19 +5203,7 @@ public class B2 : A Diagnostic(ErrorCode.WRN_NullabilityMismatchInReturnTypeOnOverride, "M5").WithLocation(21, 44), // (21,44): warning CS8610: Nullability of reference types in type of parameter 'x' doesn't match overridden member. // public override System.Action M5(System.Action x) => throw null; // warn 9 and 10 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOnOverride, "M5").WithArguments("x").WithLocation(21, 44), - // (32,14): error CS0592: Attribute 'NonNullTypes' is not valid on this declaration type. It is only valid on 'module, class, struct, enum, constructor, method, property, indexer, field, event, interface, delegate' declarations. - // [return: NonNullTypes(false)] - Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "NonNullTypes").WithArguments("NonNullTypes", "module, class, struct, enum, constructor, method, property, indexer, field, event, interface, delegate").WithLocation(32, 14), - // (33,47): error CS0592: Attribute 'NonNullTypes' is not valid on this declaration type. It is only valid on 'module, class, struct, enum, constructor, method, property, indexer, field, event, interface, delegate' declarations. - // public override System.Action M4([NonNullTypes(false)] System.Action x) => throw null; - Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "NonNullTypes").WithArguments("NonNullTypes", "module, class, struct, enum, constructor, method, property, indexer, field, event, interface, delegate").WithLocation(33, 47), - // (26,14): error CS0592: Attribute 'NonNullTypes' is not valid on this declaration type. It is only valid on 'module, class, struct, enum, constructor, method, property, indexer, field, event, interface, delegate' declarations. - // [return: NonNullTypes(false)] - Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "NonNullTypes").WithArguments("NonNullTypes", "module, class, struct, enum, constructor, method, property, indexer, field, event, interface, delegate").WithLocation(26, 14), - // (27,55): error CS0592: Attribute 'NonNullTypes' is not valid on this declaration type. It is only valid on 'module, class, struct, enum, constructor, method, property, indexer, field, event, interface, delegate' declarations. - // public override System.Action Oblivious1([NonNullTypes(false)] System.Action x) => throw null; - Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "NonNullTypes").WithArguments("NonNullTypes", "module, class, struct, enum, constructor, method, property, indexer, field, event, interface, delegate").WithLocation(27, 55) + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOnOverride, "M5").WithArguments("x").WithLocation(21, 44) ); var b1 = compilation.GetTypeByMetadataName("B1"); @@ -6216,7 +5308,6 @@ public class Class : Base where T : struct public void Overriding_Indexer() { var source = @" -using System.Runtime.CompilerServices; public class List { } public class Base { @@ -6229,17 +5320,11 @@ public class Class : Base } public class Class2 : Base { " + NonNullTypesOn() + @" - public override List this[[NonNullTypes(false)] List x] { [return: NonNullTypes(false)] get => throw null; set => throw null; } + public override List this[List x] { get => throw null; set => throw null; } } "; var comp = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue()); - comp.VerifyDiagnostics( - // (15,92): error CS0592: Attribute 'NonNullTypes' is not valid on this declaration type. It is only valid on 'module, class, struct, enum, constructor, method, property, indexer, field, event, interface, delegate' declarations. - // public override List this[[NonNullTypes(false)] List x] { [return: NonNullTypes(false)] get => throw null; set => throw null; } - Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "NonNullTypes").WithArguments("NonNullTypes", "module, class, struct, enum, constructor, method, property, indexer, field, event, interface, delegate").WithLocation(15, 92), - // (15,42): error CS0592: Attribute 'NonNullTypes' is not valid on this declaration type. It is only valid on 'module, class, struct, enum, constructor, method, property, indexer, field, event, interface, delegate' declarations. - // public override List this[[NonNullTypes(false)] List x] { [return: NonNullTypes(false)] get => throw null; set => throw null; } - Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "NonNullTypes").WithArguments("NonNullTypes", "module, class, struct, enum, constructor, method, property, indexer, field, event, interface, delegate").WithLocation(15, 42)); + comp.VerifyDiagnostics(); } [Fact] @@ -7368,7 +6453,6 @@ .assembly extern mscorlib } .module '<>.dll' -.custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor() = ( 01 00 00 00 ) .class public auto ansi beforefieldinit C`2 extends [mscorlib]System.Object @@ -7394,7 +6478,7 @@ .method public hidebysig newslot abstract virtual M1() cil managed { .param [0] - .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(bool[]) = ( 01 00 03 00 00 00 00 01 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 01 02 01 00 00 ) } // end of method A::M1 .method family hidebysig specialname rtspecialname @@ -7416,7 +6500,7 @@ extends [mscorlib]System.Attribute .custom instance void [mscorlib]System.AttributeUsageAttribute::.ctor(valuetype [mscorlib]System.AttributeTargets) = ( 01 00 86 6B 00 00 01 00 54 02 0D 41 6C 6C 6F 77 // ...k....T..Allow 4D 75 6C 74 69 70 6C 65 00 ) // Multiple. .method public hidebysig specialname rtspecialname - instance void .ctor() cil managed + instance void .ctor(uint8 transformFlag) cil managed { // Code size 9 (0x9) .maxstack 8 @@ -7428,7 +6512,7 @@ .maxstack 8 } // end of method NullableAttribute::.ctor .method public hidebysig specialname rtspecialname - instance void .ctor(bool[] transformFlags) cil managed + instance void .ctor(uint8[] transformFlags) cil managed { // Code size 9 (0x9) .maxstack 8 @@ -28531,44 +27615,44 @@ public void NullableAttribute_04() public abstract class B { - [Nullable] public string F1; - [Nullable] public event System.Action E1; - [Nullable] public string[][,] P2 {get; set;} - [return:Nullable] public System.Action M1(string? x) + [Nullable(0)] public string F1; + [Nullable(1)] public event System.Action E1; + [Nullable(2)] public string[][,] P2 {get; set;} + [return:Nullable(0)] public System.Action M1(string? x) {throw new System.NotImplementedException();} - public string[][,] M2([Nullable] string[][,] x) + public string[][,] M2([Nullable(new byte[] {0})] string[][,] x) {throw new System.NotImplementedException();} } public class C {} -[Nullable] public class F : C +[Nullable(2)] public class F : C {} "; var compilation = CreateCompilation(new[] { source, NullableAttributeDefinition }, options: WithNonNullTypesTrue()); compilation.VerifyDiagnostics( // (7,6): error CS8623: Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. - // [Nullable] public event System.Action E1; - Diagnostic(ErrorCode.ERR_ExplicitNullableAttribute, "Nullable"), + // [Nullable(1)] public event System.Action E1; + Diagnostic(ErrorCode.ERR_ExplicitNullableAttribute, "Nullable(1)").WithLocation(7, 6), // (8,6): error CS8623: Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. - // [Nullable] public string[][,] P2 {get; set;} - Diagnostic(ErrorCode.ERR_ExplicitNullableAttribute, "Nullable"), + // [Nullable(2)] public string[][,] P2 {get; set;} + Diagnostic(ErrorCode.ERR_ExplicitNullableAttribute, "Nullable(2)").WithLocation(8, 6), // (9,13): error CS8623: Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. - // [return:Nullable] public System.Action M1(string? x) - Diagnostic(ErrorCode.ERR_ExplicitNullableAttribute, "Nullable"), + // [return:Nullable(0)] public System.Action M1(string? x) + Diagnostic(ErrorCode.ERR_ExplicitNullableAttribute, "Nullable(0)").WithLocation(9, 13), // (11,28): error CS8623: Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. - // public string[][,] M2([Nullable] string[][,] x) - Diagnostic(ErrorCode.ERR_ExplicitNullableAttribute, "Nullable"), + // public string[][,] M2([Nullable(new byte[] {0})] string[][,] x) + Diagnostic(ErrorCode.ERR_ExplicitNullableAttribute, "Nullable(new byte[] {0})").WithLocation(11, 28), // (6,6): error CS8623: Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. - // [Nullable] public string F1; - Diagnostic(ErrorCode.ERR_ExplicitNullableAttribute, "Nullable"), + // [Nullable(0)] public string F1; + Diagnostic(ErrorCode.ERR_ExplicitNullableAttribute, "Nullable(0)").WithLocation(6, 6), // (17,2): error CS8623: Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. - // [Nullable] public class F : C - Diagnostic(ErrorCode.ERR_ExplicitNullableAttribute, "Nullable"), - // (7,43): warning CS0067: The event 'B.E1' is never used - // [Nullable] public event System.Action E1; - Diagnostic(ErrorCode.WRN_UnreferencedEvent, "E1").WithArguments("B.E1").WithLocation(7, 43) + // [Nullable(2)] public class F : C + Diagnostic(ErrorCode.ERR_ExplicitNullableAttribute, "Nullable(2)").WithLocation(17, 2), + // (7,46): warning CS0067: The event 'B.E1' is never used + // [Nullable(1)] public event System.Action E1; + Diagnostic(ErrorCode.WRN_UnreferencedEvent, "E1").WithArguments("B.E1").WithLocation(7, 46) ); } @@ -34280,47 +33364,6 @@ static void G6() where T : U ); } - [Fact] - public void PoisonNonNullTypes_InMetadata() - { - var il = @" -.class public auto ansi sealed beforefieldinit System.Runtime.CompilerServices.NonNullTypesAttribute - extends [mscorlib]System.Attribute -{ - .custom instance void [mscorlib]System.AttributeUsageAttribute::.ctor(valuetype [mscorlib]System.AttributeTargets) = ( - 01 00 ff 7f 00 00 01 00 54 02 0d 41 6c 6c 6f 77 - 4d 75 6c 74 69 70 6c 65 00 - ) - .custom instance void [mscorlib]System.ObsoleteAttribute::.ctor(string) = - {string('The NonNullTypes attribute is not supported in this version of your compiler. Please use a C# 8.0 compiler (or above).')} - - .method public hidebysig specialname rtspecialname instance void .ctor ( [opt] bool flag ) cil managed - { - .param [1] = bool(true) - - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Attribute::.ctor() - IL_0006: nop - IL_0007: nop - IL_0008: ret - } -} -"; - var comp = CreateCompilationWithIL("[module: System.Runtime.CompilerServices.NonNullTypes(true)]", il); - comp.VerifyDiagnostics( - // (1,10): error CS8636: Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - // [module: System.Runtime.CompilerServices.NonNullTypes(true)] - Diagnostic(ErrorCode.ERR_ExplicitNonNullTypesAttribute, "System.Runtime.CompilerServices.NonNullTypes(true)").WithLocation(1, 10) - ); - - // Injected NNT type silently wins - var tree = comp.SyntaxTrees.Single(); - var attribute = tree.GetRoot().DescendantNodes().OfType().Single(); - var model = comp.GetSemanticModel(tree); - var type = model.GetTypeInfo(attribute.Name).Type; - Assert.IsType(type); - } - [Fact] public void NonNullTypesInCSharp7_InSource() { @@ -41724,7 +40767,14 @@ void symbolValidator(ModuleSymbol m) Assert.Equal("void B.F1(T1? t1) where T1 : class", f1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); TypeParameterSymbol t1 = f1.TypeParameters[0]; Assert.False(t1.ReferenceTypeConstraintIsNullable); - Assert.Empty(t1.GetAttributes()); + if (isSource) + { + Assert.Empty(t1.GetAttributes()); + } + else + { + Assert.Equal("System.Runtime.CompilerServices.NullableAttribute(1)", t1.GetAttributes().Single().ToString()); + } var f2 = (MethodSymbol)m.GlobalNamespace.GetMember("B.F2"); Assert.Equal("void B.F2(T2 t2) where T2 : class?", f2.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); @@ -41739,7 +40789,7 @@ void symbolValidator(ModuleSymbol m) } else { - Assert.Equal("System.Runtime.CompilerServices.NullableAttribute", t2.GetAttributes().Single().ToString()); + Assert.Equal("System.Runtime.CompilerServices.NullableAttribute(2)", t2.GetAttributes().Single().ToString()); } } } @@ -41774,7 +40824,14 @@ void symbolValidator(ModuleSymbol m) Assert.Equal("A where T1 : class", a.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); TypeParameterSymbol t1 = a.TypeParameters[0]; Assert.False(t1.ReferenceTypeConstraintIsNullable); - Assert.Empty(t1.GetAttributes()); + if (isSource) + { + Assert.Empty(t1.GetAttributes()); + } + else + { + Assert.Equal("System.Runtime.CompilerServices.NullableAttribute(1)", t1.GetAttributes().Single().ToString()); + } var b = (NamedTypeSymbol)m.GlobalNamespace.GetMember("B"); Assert.Equal("B where T2 : class?", b.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); @@ -41786,7 +40843,7 @@ void symbolValidator(ModuleSymbol m) } else { - Assert.Equal("System.Runtime.CompilerServices.NullableAttribute", t2.GetAttributes().Single().ToString()); + Assert.Equal("System.Runtime.CompilerServices.NullableAttribute(2)", t2.GetAttributes().Single().ToString()); } } } @@ -41880,7 +40937,7 @@ void symbolValidator(ModuleSymbol m) } else { - Assert.Equal("System.Runtime.CompilerServices.NullableAttribute", t1.GetAttributes().Single().ToString()); + Assert.Equal("System.Runtime.CompilerServices.NullableAttribute(2)", t1.GetAttributes().Single().ToString()); } var f2 = (MethodSymbol)b.GetMember("F2"); @@ -41893,7 +40950,7 @@ void symbolValidator(ModuleSymbol m) } else { - Assert.Equal("System.Runtime.CompilerServices.NullableAttribute", t2.GetAttributes().Single().ToString()); + Assert.Equal("System.Runtime.CompilerServices.NullableAttribute(2)", t2.GetAttributes().Single().ToString()); } } @@ -42289,11 +41346,11 @@ public void Constraints_17() @" #pragma warning disable CS8321 -class B<[System.Runtime.CompilerServices.Nullable] T1> +class B<[System.Runtime.CompilerServices.Nullable(0)] T1> { - public static void F2<[System.Runtime.CompilerServices.Nullable] T2>(T2 t2) + public static void F2<[System.Runtime.CompilerServices.Nullable(1)] T2>(T2 t2) { - void F3<[System.Runtime.CompilerServices.Nullable] T3>(T3 t3) + void F3<[System.Runtime.CompilerServices.Nullable(2)] T3>(T3 t3) { } } @@ -42301,17 +41358,17 @@ class B<[System.Runtime.CompilerServices.Nullable] T1> var comp = CreateCompilation(new[] { source, NullableAttributeDefinition }); comp.VerifyDiagnostics( // (4,10): error CS8623: Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. - // class B<[System.Runtime.CompilerServices.Nullable] T1> - Diagnostic(ErrorCode.ERR_ExplicitNullableAttribute, "System.Runtime.CompilerServices.Nullable").WithLocation(4, 10), + // class B<[System.Runtime.CompilerServices.Nullable(0)] T1> + Diagnostic(ErrorCode.ERR_ExplicitNullableAttribute, "System.Runtime.CompilerServices.Nullable(0)").WithLocation(4, 10), // (6,28): error CS8623: Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. - // public static void F2<[System.Runtime.CompilerServices.Nullable] T2>(T2 t2) - Diagnostic(ErrorCode.ERR_ExplicitNullableAttribute, "System.Runtime.CompilerServices.Nullable").WithLocation(6, 28), + // public static void F2<[System.Runtime.CompilerServices.Nullable(1)] T2>(T2 t2) + Diagnostic(ErrorCode.ERR_ExplicitNullableAttribute, "System.Runtime.CompilerServices.Nullable(1)").WithLocation(6, 28), // (8,17): error CS8205: Attributes are not allowed on local function parameters or type parameters - // void F3<[System.Runtime.CompilerServices.Nullable] T3>(T3 t3) - Diagnostic(ErrorCode.ERR_AttributesInLocalFuncDecl, "[System.Runtime.CompilerServices.Nullable]").WithLocation(8, 17), + // void F3<[System.Runtime.CompilerServices.Nullable(2)] T3>(T3 t3) + Diagnostic(ErrorCode.ERR_AttributesInLocalFuncDecl, "[System.Runtime.CompilerServices.Nullable(2)]").WithLocation(8, 17), // (8,18): error CS8623: Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. - // void F3<[System.Runtime.CompilerServices.Nullable] T3>(T3 t3) - Diagnostic(ErrorCode.ERR_ExplicitNullableAttribute, "System.Runtime.CompilerServices.Nullable").WithLocation(8, 18) + // void F3<[System.Runtime.CompilerServices.Nullable(2)] T3>(T3 t3) + Diagnostic(ErrorCode.ERR_ExplicitNullableAttribute, "System.Runtime.CompilerServices.Nullable(2)").WithLocation(8, 18) ); } @@ -42355,13 +41412,27 @@ void symbolValidator(ModuleSymbol m) Assert.Equal("void B.F1(T11? t1) where T11 : class", bf1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); TypeParameterSymbol t11 = bf1.TypeParameters[0]; Assert.False(t11.ReferenceTypeConstraintIsNullable); - Assert.Empty(t11.GetAttributes()); + if (isSource) + { + Assert.Empty(t11.GetAttributes()); + } + else + { + Assert.Equal("System.Runtime.CompilerServices.NullableAttribute(1)", t11.GetAttributes().Single().ToString()); + } var af1 = bf1.OverriddenMethod; Assert.Equal("void A.F1(T1? t1) where T1 : class", af1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); TypeParameterSymbol t1 = af1.TypeParameters[0]; Assert.False(t1.ReferenceTypeConstraintIsNullable); - Assert.Empty(t1.GetAttributes()); + if (isSource) + { + Assert.Empty(t1.GetAttributes()); + } + else + { + Assert.Equal("System.Runtime.CompilerServices.NullableAttribute(1)", t1.GetAttributes().Single().ToString()); + } var bf2 = (MethodSymbol)m.GlobalNamespace.GetMember("B.F2"); Assert.Equal("void B.F2(T22 t2) where T22 : class?", bf2.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); @@ -42374,7 +41445,7 @@ void symbolValidator(ModuleSymbol m) } else { - Assert.Equal("System.Runtime.CompilerServices.NullableAttribute", t22.GetAttributes().Single().ToString()); + Assert.Equal("System.Runtime.CompilerServices.NullableAttribute(2)", t22.GetAttributes().Single().ToString()); } var af2 = bf2.OverriddenMethod; @@ -42388,7 +41459,7 @@ void symbolValidator(ModuleSymbol m) } else { - Assert.Equal("System.Runtime.CompilerServices.NullableAttribute", t2.GetAttributes().Single().ToString()); + Assert.Equal("System.Runtime.CompilerServices.NullableAttribute(2)", t2.GetAttributes().Single().ToString()); } } } @@ -42436,7 +41507,14 @@ void symbolValidator(ModuleSymbol m) Assert.Equal("void B.F1(T11? t1) where T11 : class", bf1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); TypeParameterSymbol t11 = bf1.TypeParameters[0]; Assert.False(t11.ReferenceTypeConstraintIsNullable); - Assert.Empty(t11.GetAttributes()); + if (isSource) + { + Assert.Empty(t11.GetAttributes()); + } + else + { + Assert.Equal("System.Runtime.CompilerServices.NullableAttribute(1)", t11.GetAttributes().Single().ToString()); + } var bf2 = (MethodSymbol)m.GlobalNamespace.GetMember("B.F2"); Assert.Equal("void B.F2(T22 t2) where T22 : class?", bf2.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); @@ -42450,7 +41528,7 @@ void symbolValidator(ModuleSymbol m) else { CSharpAttributeData nullableAttribute = t22.GetAttributes().Single(); - Assert.Equal("System.Runtime.CompilerServices.NullableAttribute", nullableAttribute.ToString()); + Assert.Equal("System.Runtime.CompilerServices.NullableAttribute(2)", nullableAttribute.ToString()); Assert.Same(m, nullableAttribute.AttributeClass.ContainingModule); Assert.Equal(Accessibility.Internal, nullableAttribute.AttributeClass.DeclaredAccessibility); } @@ -42504,7 +41582,14 @@ void symbolValidator(ModuleSymbol m) Assert.Equal("void B.F1(T11? t1) where T11 : class", bf1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); TypeParameterSymbol t11 = bf1.TypeParameters[0]; Assert.False(t11.ReferenceTypeConstraintIsNullable); - Assert.Empty(t11.GetAttributes()); + if (isSource) + { + Assert.Empty(t11.GetAttributes()); + } + else + { + Assert.Equal("System.Runtime.CompilerServices.NullableAttribute(1)", t11.GetAttributes().Single().ToString()); + } var bf2 = (MethodSymbol)m.GlobalNamespace.GetMember("B.F2"); Assert.Equal("void B.F2(T22 t2) where T22 : class?", bf2.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); @@ -42518,7 +41603,7 @@ void symbolValidator(ModuleSymbol m) else { CSharpAttributeData nullableAttribute = t22.GetAttributes().Single(); - Assert.Equal("System.Runtime.CompilerServices.NullableAttribute", nullableAttribute.ToString()); + Assert.Equal("System.Runtime.CompilerServices.NullableAttribute(2)", nullableAttribute.ToString()); Assert.NotEqual(m, nullableAttribute.AttributeClass.ContainingModule); } } @@ -42568,21 +41653,16 @@ void symbolValidator(ModuleSymbol m) var bf1 = (MethodSymbol)m.GlobalNamespace.GetMember("B.F1"); Assert.Equal("void B.F1() where T11 : class", bf1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); TypeParameterSymbol t11 = bf1.TypeParameters[0]; - - // https://github.com/dotnet/roslyn/issues/29979: It is probably wrong to have this difference between source symbol - // and emitted-then-imported symbol. What are the rules for inheriting constraints - // across different non-null contexts? + Assert.False(t11.ReferenceTypeConstraintIsNullable); if (isSource) { - Assert.False(t11.ReferenceTypeConstraintIsNullable); + Assert.Empty(t11.GetAttributes()); } else { - Assert.Null(t11.ReferenceTypeConstraintIsNullable); + Assert.Equal("System.Runtime.CompilerServices.NullableAttribute(1)", t11.GetAttributes().Single().ToString()); } - Assert.Empty(t11.GetAttributes()); - var bf2 = (MethodSymbol)m.GlobalNamespace.GetMember("B.F2"); Assert.Equal("void B.F2() where T22 : class?", bf2.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); @@ -42594,7 +41674,7 @@ void symbolValidator(ModuleSymbol m) } else { - Assert.Equal("System.Runtime.CompilerServices.NullableAttribute", t22.GetAttributes().Single().ToString()); + Assert.Equal("System.Runtime.CompilerServices.NullableAttribute(2)", t22.GetAttributes().Single().ToString()); } } } @@ -42767,7 +41847,14 @@ void symbolValidator(ModuleSymbol m) Assert.Equal("void B.F1() where T11 : class", bf1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); TypeParameterSymbol t11 = bf1.TypeParameters[0]; Assert.False(t11.ReferenceTypeConstraintIsNullable); - Assert.Empty(t11.GetAttributes()); + if (isSource) + { + Assert.Empty(t11.GetAttributes()); + } + else + { + Assert.Equal("System.Runtime.CompilerServices.NullableAttribute(1)", t11.GetAttributes().Single().ToString()); + } var bf2 = (MethodSymbol)m.GlobalNamespace.GetMember("B.F2"); Assert.Equal("void B.F2() where T22 : class?", bf2.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); @@ -42780,7 +41867,7 @@ void symbolValidator(ModuleSymbol m) } else { - Assert.Equal("System.Runtime.CompilerServices.NullableAttribute", t22.GetAttributes().Single().ToString()); + Assert.Equal("System.Runtime.CompilerServices.NullableAttribute(2)", t22.GetAttributes().Single().ToString()); } var bf3 = (MethodSymbol)m.GlobalNamespace.GetMember("B.F3"); @@ -42865,7 +41952,14 @@ void symbolValidator(ModuleSymbol m) Assert.Equal("void B.IA.F1() where T11 : class", bf1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); TypeParameterSymbol t11 = bf1.TypeParameters[0]; Assert.False(t11.ReferenceTypeConstraintIsNullable); - Assert.Empty(t11.GetAttributes()); + if (isSource) + { + Assert.Empty(t11.GetAttributes()); + } + else + { + Assert.Equal("System.Runtime.CompilerServices.NullableAttribute(1)", t11.GetAttributes().Single().ToString()); + } var bf2 = (MethodSymbol)m.GlobalNamespace.GetMember("B.IA.F2"); Assert.Equal("void B.IA.F2() where T22 : class?", bf2.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); @@ -42878,7 +41972,7 @@ void symbolValidator(ModuleSymbol m) } else { - Assert.Equal("System.Runtime.CompilerServices.NullableAttribute", t22.GetAttributes().Single().ToString()); + Assert.Equal("System.Runtime.CompilerServices.NullableAttribute(2)", t22.GetAttributes().Single().ToString()); } } } @@ -42922,7 +42016,14 @@ void symbolValidator(ModuleSymbol m) Assert.Equal("void B.IA.F1() where T11 : class", bf1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); TypeParameterSymbol t11 = bf1.TypeParameters[0]; Assert.False(t11.ReferenceTypeConstraintIsNullable); - Assert.Empty(t11.GetAttributes()); + if (isSource) + { + Assert.Empty(t11.GetAttributes()); + } + else + { + Assert.Equal("System.Runtime.CompilerServices.NullableAttribute(1)", t11.GetAttributes().Single().ToString()); + } var bf2 = (MethodSymbol)m.GlobalNamespace.GetMember("B.IA.F2"); Assert.Equal("void B.IA.F2() where T22 : class?", bf2.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); @@ -42936,7 +42037,7 @@ void symbolValidator(ModuleSymbol m) else { CSharpAttributeData nullableAttribute = t22.GetAttributes().Single(); - Assert.Equal("System.Runtime.CompilerServices.NullableAttribute", nullableAttribute.ToString()); + Assert.Equal("System.Runtime.CompilerServices.NullableAttribute(2)", nullableAttribute.ToString()); Assert.Same(m, nullableAttribute.AttributeClass.ContainingModule); Assert.Equal(Accessibility.Internal, nullableAttribute.AttributeClass.DeclaredAccessibility); } @@ -42986,7 +42087,14 @@ void symbolValidator(ModuleSymbol m) Assert.Equal("void B.IA.F1() where T11 : class", bf1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); TypeParameterSymbol t11 = bf1.TypeParameters[0]; Assert.False(t11.ReferenceTypeConstraintIsNullable); - Assert.Empty(t11.GetAttributes()); + if (isSource) + { + Assert.Empty(t11.GetAttributes()); + } + else + { + Assert.Equal("System.Runtime.CompilerServices.NullableAttribute(1)", t11.GetAttributes().Single().ToString()); + } var bf2 = (MethodSymbol)m.GlobalNamespace.GetMember("B.IA.F2"); Assert.Equal("void B.IA.F2() where T22 : class?", bf2.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); @@ -43000,7 +42108,7 @@ void symbolValidator(ModuleSymbol m) else { CSharpAttributeData nullableAttribute = t22.GetAttributes().Single(); - Assert.Equal("System.Runtime.CompilerServices.NullableAttribute", nullableAttribute.ToString()); + Assert.Equal("System.Runtime.CompilerServices.NullableAttribute(2)", nullableAttribute.ToString()); Assert.NotEqual(m, nullableAttribute.AttributeClass.ContainingModule); } } @@ -43045,21 +42153,16 @@ void symbolValidator(ModuleSymbol m) var bf1 = (MethodSymbol)m.GlobalNamespace.GetMember("B.IA.F1"); Assert.Equal("void B.IA.F1() where T11 : class", bf1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); TypeParameterSymbol t11 = bf1.TypeParameters[0]; - - // https://github.com/dotnet/roslyn/issues/29979: It is probably wrong to have this difference between source symbol - // and emitted-then-imported symbol. What are the rules for inheriting constraints - // across different non-null contexts? + Assert.False(t11.ReferenceTypeConstraintIsNullable); if (isSource) { - Assert.False(t11.ReferenceTypeConstraintIsNullable); + Assert.Empty(t11.GetAttributes()); } else { - Assert.Null(t11.ReferenceTypeConstraintIsNullable); + Assert.Equal("System.Runtime.CompilerServices.NullableAttribute(1)", t11.GetAttributes().Single().ToString()); } - Assert.Empty(t11.GetAttributes()); - var bf2 = (MethodSymbol)m.GlobalNamespace.GetMember("B.IA.F2"); Assert.Equal("void B.IA.F2() where T22 : class?", bf2.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); @@ -43071,7 +42174,7 @@ void symbolValidator(ModuleSymbol m) } else { - Assert.Equal("System.Runtime.CompilerServices.NullableAttribute", t22.GetAttributes().Single().ToString()); + Assert.Equal("System.Runtime.CompilerServices.NullableAttribute(2)", t22.GetAttributes().Single().ToString()); } } } @@ -43149,7 +42252,7 @@ void symbolValidator(ModuleSymbol m) } else { - Assert.Equal("System.Runtime.CompilerServices.NullableAttribute", t2.GetAttributes().Single().ToString()); + Assert.Equal("System.Runtime.CompilerServices.NullableAttribute(2)", t2.GetAttributes().Single().ToString()); } } } @@ -43181,7 +42284,7 @@ void symbolValidator(ModuleSymbol m) } else { - Assert.Equal("System.Runtime.CompilerServices.NullableAttribute", t2.GetAttributes().Single().ToString()); + Assert.Equal("System.Runtime.CompilerServices.NullableAttribute(2)", t2.GetAttributes().Single().ToString()); } } } @@ -43426,7 +42529,14 @@ void symbolValidator(ModuleSymbol m) Assert.Equal("void B.F1() where T11 : class", bf1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); TypeParameterSymbol t11 = bf1.TypeParameters[0]; Assert.False(t11.ReferenceTypeConstraintIsNullable); - Assert.Empty(t11.GetAttributes()); + if (isSource) + { + Assert.Empty(t11.GetAttributes()); + } + else + { + Assert.Equal("System.Runtime.CompilerServices.NullableAttribute(1)", t11.GetAttributes().Single().ToString()); + } var bf2 = (MethodSymbol)m.GlobalNamespace.GetMember("B.F2"); Assert.Equal("void B.F2() where T22 : class?", bf2.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); @@ -43439,7 +42549,7 @@ void symbolValidator(ModuleSymbol m) } else { - Assert.Equal("System.Runtime.CompilerServices.NullableAttribute", t22.GetAttributes().Single().ToString()); + Assert.Equal("System.Runtime.CompilerServices.NullableAttribute(2)", t22.GetAttributes().Single().ToString()); } var bf3 = (MethodSymbol)m.GlobalNamespace.GetMember("B.F3"); @@ -50266,116 +49376,6 @@ class C comp.VerifyDiagnostics(); } - [WorkItem(29186, "https://github.com/dotnet/roslyn/issues/29186")] - [Fact] - public void AttributeArgumentCycle_NonNullTypes_01() - { - var source = -@"using System.Runtime.CompilerServices; -class A { } -class B where T : A { } -[NonNullTypes(typeof(B))] -class C -{ -}"; - var comp = CreateCompilation(new[] { source }, options: WithNonNullTypesFalse()); - comp.VerifyDiagnostics( - // (4,15): error CS1503: Argument 1: cannot convert from 'System.Type' to 'bool' - // [NonNullTypes(typeof(B))] - Diagnostic(ErrorCode.ERR_BadArgType, "typeof(B)").WithArguments("1", "System.Type", "bool").WithLocation(4, 15)); - } - - [WorkItem(29186, "https://github.com/dotnet/roslyn/issues/29186")] - [Fact] - public void AttributeArgumentCycle_NonNullTypes_02() - { - var source = -@"using System.Runtime.CompilerServices; -class A { } -class B where T : A -{ - internal const bool True = true; -} -[NonNullTypes(B.True)] -class C -{ -} -[NonNullTypes(B.True)] -class D -{ -}"; - var comp = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue(), parseOptions: TestOptions.Regular7_3, skipUsesIsNullable: true); - comp.VerifyDiagnostics( - // error CS8630: Invalid 'Nullable' value: 'True' for C# 7.3. Please use language version 8.0 or greater. - Diagnostic(ErrorCode.ERR_NullableOptionNotAvailable).WithArguments("Nullable", "True", "7.3", "8.0").WithLocation(1, 1), - // (7,2): error CS8636: Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - // [NonNullTypes(B.True)] - Diagnostic(ErrorCode.ERR_ExplicitNonNullTypesAttribute, "NonNullTypes(B.True)").WithLocation(7, 2), - // (11,18): error CS8370: Feature 'nullable reference types' is not available in C# 7.3. Please use language version 8.0 or greater. - // [NonNullTypes(B.True)] - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "?").WithArguments("nullable reference types", "8.0").WithLocation(11, 18), - // (11,2): error CS8636: Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - // [NonNullTypes(B.True)] - Diagnostic(ErrorCode.ERR_ExplicitNonNullTypesAttribute, "NonNullTypes(B.True)").WithLocation(11, 2)); - - var comp2 = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue()); - comp2.VerifyDiagnostics( - // (7,2): error CS8636: Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - // [NonNullTypes(B.True)] - Diagnostic(ErrorCode.ERR_ExplicitNonNullTypesAttribute, "NonNullTypes(B.True)").WithLocation(7, 2), - // (11,2): error CS8636: Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - // [NonNullTypes(B.True)] - Diagnostic(ErrorCode.ERR_ExplicitNonNullTypesAttribute, "NonNullTypes(B.True)").WithLocation(11, 2), - // (11,15): warning CS8631: The type 'A?' cannot be used as type parameter 'T' in the generic type or method 'B'. Nullability of type argument 'A?' doesn't match constraint type 'A'. - // [NonNullTypes(B.True)] - Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "B").WithArguments("B", "A", "T", "A?").WithLocation(11, 15)); - } - - [WorkItem(29186, "https://github.com/dotnet/roslyn/issues/29186")] - [Fact] - public void AttributeArgumentCycle_Nullable() - { - var source0 = -@" - -namespace System -{ - public class Object { } - public abstract class ValueType { } - public struct Void { } - public struct Int32 { } - public class Type { } - public struct Boolean { } - public struct Enum { } - public class Attribute { } - public interface INullable { } - public struct Nullable where T : INullable { } -} -namespace System.Runtime.CompilerServices -{ - public sealed class NonNullTypesAttribute : Attribute - { - public NonNullTypesAttribute(bool flag = true) { } - } -}"; - var source = -@"using System; -class AAttribute : Attribute -{ - internal AAttribute(object o) { } -} -struct S : INullable { } -[A(typeof(S?))] -class C -{ -}"; - var comp = CreateEmptyCompilation(new[] { source0, source }, options: WithNonNullTypesTrue()); - comp.VerifyDiagnostics( - // (7,11): warning CS8631: The type 'S' cannot be used as type parameter 'T' in the generic type or method 'Nullable'. Nullability of type argument 'S' doesn't match constraint type 'System.INullable'. - // [A(typeof(S?))] - Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "S?").WithArguments("System.Nullable", "System.INullable", "T", "S").WithLocation(7, 11)); - } - [Fact] [WorkItem(30178, "https://github.com/dotnet/roslyn/issues/30178")] public void GenericSubstitution_01() @@ -50939,165 +49939,6 @@ class C {} ); } - [Fact] - public void NonNullTypes_27() - { - var source = -@"using System.Runtime.CompilerServices; - -[module: NonNullTypes] // 1 - -[NonNullTypes] // 2 -class A -{ - [NonNullTypes] // 3 - string F1; - - [NonNullTypes] // 4 - string P1 {get; set;} - - [NonNullTypes] // 5 - void M1() {} - - [NonNullTypes] // 6 - event System.Action E1; -} -"; - var comp = CreateCompilation(new[] { source }); - comp.VerifyDiagnostics( - // (3,10): error CS8636: Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - // [module: NonNullTypes] // 1 - Diagnostic(ErrorCode.ERR_ExplicitNonNullTypesAttribute, "NonNullTypes").WithLocation(3, 10), - // (5,2): error CS8636: Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - // [NonNullTypes] // 2 - Diagnostic(ErrorCode.ERR_ExplicitNonNullTypesAttribute, "NonNullTypes").WithLocation(5, 2), - // (8,6): error CS8636: Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - // [NonNullTypes] // 3 - Diagnostic(ErrorCode.ERR_ExplicitNonNullTypesAttribute, "NonNullTypes").WithLocation(8, 6), - // (9,12): warning CS0169: The field 'A.F1' is never used - // string F1; - Diagnostic(ErrorCode.WRN_UnreferencedField, "F1").WithArguments("A.F1").WithLocation(9, 12), - // (11,6): error CS8636: Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - // [NonNullTypes] // 4 - Diagnostic(ErrorCode.ERR_ExplicitNonNullTypesAttribute, "NonNullTypes").WithLocation(11, 6), - // (14,6): error CS8636: Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - // [NonNullTypes] // 5 - Diagnostic(ErrorCode.ERR_ExplicitNonNullTypesAttribute, "NonNullTypes").WithLocation(14, 6), - // (17,6): error CS8636: Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - // [NonNullTypes] // 6 - Diagnostic(ErrorCode.ERR_ExplicitNonNullTypesAttribute, "NonNullTypes").WithLocation(17, 6), - // (18,25): warning CS0067: The event 'A.E1' is never used - // event System.Action E1; - Diagnostic(ErrorCode.WRN_UnreferencedEvent, "E1").WithArguments("A.E1").WithLocation(18, 25) -); - } - - [Fact] - public void NonNullTypes_28() - { - var source = -@"using System.Runtime.CompilerServices; - -[module: NonNullTypes(false)] // 1 - -[NonNullTypes(false)] // 2 -class A -{ - [NonNullTypes(false)] // 3 - string F1; - - [NonNullTypes(false)] // 4 - string P1 {get; set;} - - [NonNullTypes(false)] // 5 - void M1() {} - - [NonNullTypes(false)] // 6 - event System.Action E1; -} -"; - var comp = CreateCompilation(new[] { source }); - comp.VerifyDiagnostics( - // (3,10): error CS8636: Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - // [module: NonNullTypes(false)] // 1 - Diagnostic(ErrorCode.ERR_ExplicitNonNullTypesAttribute, "NonNullTypes(false)").WithLocation(3, 10), - // (5,2): error CS8636: Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - // [NonNullTypes(false)] // 2 - Diagnostic(ErrorCode.ERR_ExplicitNonNullTypesAttribute, "NonNullTypes(false)").WithLocation(5, 2), - // (8,6): error CS8636: Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - // [NonNullTypes(false)] // 3 - Diagnostic(ErrorCode.ERR_ExplicitNonNullTypesAttribute, "NonNullTypes(false)").WithLocation(8, 6), - // (9,12): warning CS0169: The field 'A.F1' is never used - // string F1; - Diagnostic(ErrorCode.WRN_UnreferencedField, "F1").WithArguments("A.F1").WithLocation(9, 12), - // (11,6): error CS8636: Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - // [NonNullTypes(false)] // 4 - Diagnostic(ErrorCode.ERR_ExplicitNonNullTypesAttribute, "NonNullTypes(false)").WithLocation(11, 6), - // (14,6): error CS8636: Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - // [NonNullTypes(false)] // 5 - Diagnostic(ErrorCode.ERR_ExplicitNonNullTypesAttribute, "NonNullTypes(false)").WithLocation(14, 6), - // (17,6): error CS8636: Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - // [NonNullTypes(false)] // 6 - Diagnostic(ErrorCode.ERR_ExplicitNonNullTypesAttribute, "NonNullTypes(false)").WithLocation(17, 6), - // (18,25): warning CS0067: The event 'A.E1' is never used - // event System.Action E1; - Diagnostic(ErrorCode.WRN_UnreferencedEvent, "E1").WithArguments("A.E1").WithLocation(18, 25) -); - } - - [Fact] - public void NonNullTypes_29() - { - var source = -@"using System.Runtime.CompilerServices; - -[module: NonNullTypes(true)] // 1 - -[NonNullTypes(true)] // 2 -class A -{ - [NonNullTypes(true)] // 3 - string F1; - - [NonNullTypes(true)] // 4 - string P1 {get; set;} - - [NonNullTypes(true)] // 5 - void M1() {} - - [NonNullTypes(true)] // 6 - event System.Action E1; -} -"; - var comp = CreateCompilation(new[] { source }); - comp.VerifyDiagnostics( - // (3,10): error CS8636: Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - // [module: NonNullTypes(true)] // 1 - Diagnostic(ErrorCode.ERR_ExplicitNonNullTypesAttribute, "NonNullTypes(true)").WithLocation(3, 10), - // (5,2): error CS8636: Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - // [NonNullTypes(true)] // 2 - Diagnostic(ErrorCode.ERR_ExplicitNonNullTypesAttribute, "NonNullTypes(true)").WithLocation(5, 2), - // (8,6): error CS8636: Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - // [NonNullTypes(true)] // 3 - Diagnostic(ErrorCode.ERR_ExplicitNonNullTypesAttribute, "NonNullTypes(true)").WithLocation(8, 6), - // (9,12): warning CS0169: The field 'A.F1' is never used - // string F1; - Diagnostic(ErrorCode.WRN_UnreferencedField, "F1").WithArguments("A.F1").WithLocation(9, 12), - // (11,6): error CS8636: Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - // [NonNullTypes(true)] // 4 - Diagnostic(ErrorCode.ERR_ExplicitNonNullTypesAttribute, "NonNullTypes(true)").WithLocation(11, 6), - // (14,6): error CS8636: Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - // [NonNullTypes(true)] // 5 - Diagnostic(ErrorCode.ERR_ExplicitNonNullTypesAttribute, "NonNullTypes(true)").WithLocation(14, 6), - // (17,6): error CS8636: Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - // [NonNullTypes(true)] // 6 - Diagnostic(ErrorCode.ERR_ExplicitNonNullTypesAttribute, "NonNullTypes(true)").WithLocation(17, 6), - // (18,25): warning CS0067: The event 'A.E1' is never used - // event System.Action E1; - Diagnostic(ErrorCode.WRN_UnreferencedEvent, "E1").WithArguments("A.E1").WithLocation(18, 25) -); - } - [WorkItem(23270, "https://github.com/dotnet/roslyn/issues/23270")] [Fact] public void NotNullAfterDereference_01() @@ -51948,8 +50789,12 @@ static void Main() // @"!!X modopt([mscorlib]System.Runtime.CompilerServices.IsConst)[] modopt([mscorlib]System.Runtime.CompilerServices.IsConst) z) cil managed") Signature("Metadata.GD", "Method", @".method public hidebysig virtual instance System.Void Method(" + + @"[System.Runtime.CompilerServices.NullableAttribute(1)] " + @"modopt(System.Runtime.CompilerServices.IsConst) System.String[] x, " + - @"modopt(System.Runtime.CompilerServices.IsConst) System.UInt64[] y, modopt(System.Runtime.CompilerServices.IsConst) X[] z) cil managed"), + @"[System.Runtime.CompilerServices.NullableAttribute(System.Collections.ObjectModel.ReadOnlyCollection`1[System.Reflection.CustomAttributeTypedArgument])] " + + @"modopt(System.Runtime.CompilerServices.IsConst) System.UInt64[] y, "+ + @"[System.Runtime.CompilerServices.NullableAttribute(1)] " + + @"modopt(System.Runtime.CompilerServices.IsConst) X[] z) cil managed"), }); } diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/MissingSpecialMember.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/MissingSpecialMember.cs index 7aadd9cb137a2..82f0a2dfeada3 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/MissingSpecialMember.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/MissingSpecialMember.cs @@ -564,7 +564,6 @@ public void AllWellKnownTypes() case WellKnownType.System_Span_T: case WellKnownType.System_ReadOnlySpan_T: case WellKnownType.System_Runtime_CompilerServices_IsUnmanagedAttribute: - case WellKnownType.System_Runtime_CompilerServices_NonNullTypesAttribute: case WellKnownType.System_Index: case WellKnownType.System_Range: case WellKnownType.System_IAsyncDisposable: @@ -875,7 +874,7 @@ public void AllWellKnownTypeMembers() // C# can't embed VB core. continue; case WellKnownMember.System_Array__Empty: - case WellKnownMember.System_Runtime_CompilerServices_NullableAttribute__ctor: + case WellKnownMember.System_Runtime_CompilerServices_NullableAttribute__ctorByte: case WellKnownMember.System_Runtime_CompilerServices_NullableAttribute__ctorTransformFlags: case WellKnownMember.System_Span_T__ctor: case WellKnownMember.System_Span_T__get_Item: diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/Retargeting/NoPia.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/Retargeting/NoPia.cs index 3e3e649fe5aae..f466429a11569 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/Retargeting/NoPia.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/Retargeting/NoPia.cs @@ -291,12 +291,10 @@ public void HideLocalTypeDefinitions() Assert.Same(assemblies[2], LocalTypes1.Assembly.CorLibrary); Assert.Same(assemblies[2], LocalTypes2.Assembly.CorLibrary); - Assert.Equal(4, localTypes1.GlobalNamespace.GetMembers().Length); - Assert.Equal(4, localTypes1.GlobalNamespace.GetMembersUnordered().Length); + Assert.Equal(2, localTypes1.GlobalNamespace.GetMembers().Length); + Assert.Equal(2, localTypes1.GlobalNamespace.GetMembersUnordered().Length); Assert.Equal(0, localTypes1.GlobalNamespace.GetMembers("I1").Length); Assert.Equal(0, localTypes1.GlobalNamespace.GetMembers("S1").Length); - Assert.Equal(1, localTypes1.GlobalNamespace.GetMembers("System").Length); - Assert.Equal(1, localTypes1.GlobalNamespace.GetMembers("Microsoft").Length); Assert.Equal(1, localTypes1.GlobalNamespace.GetTypeMembers().Length); Assert.Equal(0, localTypes1.GlobalNamespace.GetTypeMembers("I1").Length); Assert.Equal(0, localTypes1.GlobalNamespace.GetTypeMembers("S1").Length); @@ -305,12 +303,10 @@ public void HideLocalTypeDefinitions() Assert.Equal(0, localTypes1.GlobalNamespace.GetMembers("NS1").OfType().Single(). GetTypeMembers().Length); - Assert.Equal(4, localTypes2.GlobalNamespace.GetMembers().Length); - Assert.Equal(4, localTypes2.GlobalNamespace.GetMembersUnordered().Length); + Assert.Equal(2, localTypes2.GlobalNamespace.GetMembers().Length); + Assert.Equal(2, localTypes2.GlobalNamespace.GetMembersUnordered().Length); Assert.Equal(0, localTypes2.GlobalNamespace.GetMembers("I1").Length); Assert.Equal(0, localTypes2.GlobalNamespace.GetMembers("S1").Length); - Assert.Equal(1, localTypes2.GlobalNamespace.GetMembers("System").Length); - Assert.Equal(1, localTypes2.GlobalNamespace.GetMembers("Microsoft").Length); Assert.Equal(1, localTypes2.GlobalNamespace.GetTypeMembers().Length); Assert.Equal(0, localTypes2.GlobalNamespace.GetTypeMembers("I1").Length); Assert.Equal(0, localTypes2.GlobalNamespace.GetTypeMembers("S1").Length); diff --git a/src/Compilers/Core/Portable/Emit/CommonPEModuleBuilder.cs b/src/Compilers/Core/Portable/Emit/CommonPEModuleBuilder.cs index 6ad0f61466220..d210b95e6bef4 100644 --- a/src/Compilers/Core/Portable/Emit/CommonPEModuleBuilder.cs +++ b/src/Compilers/Core/Portable/Emit/CommonPEModuleBuilder.cs @@ -425,8 +425,6 @@ internal abstract class PEModuleBuilder GetInjectedTypes(DiagnosticBag diagnostics); - internal abstract Cci.IAssemblyReference Translate(TAssemblySymbol symbol, DiagnosticBag diagnostics); internal abstract Cci.ITypeReference Translate(TTypeSymbol symbol, TSyntaxNode syntaxNodeOpt, DiagnosticBag diagnostics); internal abstract Cci.IMethodReference Translate(TMethodSymbol symbol, DiagnosticBag diagnostics, bool needDeclaration); diff --git a/src/Compilers/Core/Portable/Emit/EditAndContinue/DeltaMetadataWriter.cs b/src/Compilers/Core/Portable/Emit/EditAndContinue/DeltaMetadataWriter.cs index d3029e2e9f6f4..c461cbbae3813 100644 --- a/src/Compilers/Core/Portable/Emit/EditAndContinue/DeltaMetadataWriter.cs +++ b/src/Compilers/Core/Portable/Emit/EditAndContinue/DeltaMetadataWriter.cs @@ -1444,9 +1444,6 @@ public DeltaReferenceIndexer(DeltaMetadataWriter writer) _changes = writer._changes; } - protected override bool ProcessReferencesInCurrentModule - => false; - public override void Visit(CommonPEModuleBuilder module) { this.Visit(((DeltaMetadataWriter)this.metadataWriter).GetTopLevelTypes(module)); diff --git a/src/Compilers/Core/Portable/MetadataReader/PEModule.cs b/src/Compilers/Core/Portable/MetadataReader/PEModule.cs index 8d49684c6b153..cbb9f0aae4c0f 100644 --- a/src/Compilers/Core/Portable/MetadataReader/PEModule.cs +++ b/src/Compilers/Core/Portable/MetadataReader/PEModule.cs @@ -82,12 +82,14 @@ internal sealed class PEModule : IDisposable private static readonly AttributeValueExtractor s_attributeStringValueExtractor = CrackStringInAttributeValue; private static readonly AttributeValueExtractor s_attributeStringAndIntValueExtractor = CrackStringAndIntInAttributeValue; private static readonly AttributeValueExtractor s_attributeBooleanValueExtractor = CrackBooleanInAttributeValue; + private static readonly AttributeValueExtractor s_attributeByteValueExtractor = CrackByteInAttributeValue; private static readonly AttributeValueExtractor s_attributeShortValueExtractor = CrackShortInAttributeValue; private static readonly AttributeValueExtractor s_attributeIntValueExtractor = CrackIntInAttributeValue; private static readonly AttributeValueExtractor s_attributeLongValueExtractor = CrackLongInAttributeValue; // Note: not a general purpose helper private static readonly AttributeValueExtractor s_decimalValueInDecimalConstantAttributeExtractor = CrackDecimalInDecimalConstantAttribute; private static readonly AttributeValueExtractor> s_attributeBoolArrayValueExtractor = CrackBoolArrayInAttributeValue; + private static readonly AttributeValueExtractor> s_attributeByteArrayValueExtractor = CrackByteArrayInAttributeValue; private static readonly AttributeValueExtractor> s_attributeStringArrayValueExtractor = CrackStringArrayInAttributeValue; private static readonly AttributeValueExtractor s_attributeObsoleteDataExtractor = CrackObsoleteAttributeData; private static readonly AttributeValueExtractor s_attributeDeprecatedDataExtractor = CrackDeprecatedAttributeData; @@ -1000,7 +1002,7 @@ internal CustomAttributeHandle GetAttributeHandle(EntityHandle token, AttributeD return FindTargetAttribute(token, description).Handle; } - private static readonly ImmutableArray s_simpleDynamicOrNullableTransforms = ImmutableArray.Create(true); + private static readonly ImmutableArray s_simpleDynamicTransforms = ImmutableArray.Create(true); internal bool HasDynamicAttribute(EntityHandle token, out ImmutableArray dynamicTransforms) { @@ -1015,7 +1017,7 @@ internal bool HasDynamicAttribute(EntityHandle token, out ImmutableArray d if (info.SignatureIndex == 0) { - dynamicTransforms = s_simpleDynamicOrNullableTransforms; + dynamicTransforms = s_simpleDynamicTransforms; return true; } @@ -1367,6 +1369,11 @@ private bool TryExtractBoolArrayValueFromAttribute(CustomAttributeHandle handle, return TryExtractValueFromAttribute(handle, out value, s_attributeBoolArrayValueExtractor); } + private bool TryExtractByteArrayValueFromAttribute(CustomAttributeHandle handle, out ImmutableArray value) + { + return TryExtractValueFromAttribute(handle, out value, s_attributeByteArrayValueExtractor); + } + private bool TryExtractStringArrayValueFromAttribute(CustomAttributeHandle handle, out ImmutableArray value) { return TryExtractValueFromAttribute(handle, out value, s_attributeStringArrayValueExtractor); @@ -1664,13 +1671,13 @@ internal static bool CrackBoolArrayInAttributeValue(out ImmutableArray val uint arrayLen = sig.ReadUInt32(); if (sig.RemainingBytes >= arrayLen) { - var boolArray = new bool[arrayLen]; + var boolArrayBuilder = ArrayBuilder.GetInstance((int)arrayLen); for (int i = 0; i < arrayLen; i++) { - boolArray[i] = (sig.ReadByte() == 1); + boolArrayBuilder.Add(sig.ReadByte() == 1); } - value = boolArray.AsImmutableOrNull(); + value = boolArrayBuilder.ToImmutableAndFree(); return true; } } @@ -1679,6 +1686,28 @@ internal static bool CrackBoolArrayInAttributeValue(out ImmutableArray val return false; } + internal static bool CrackByteArrayInAttributeValue(out ImmutableArray value, ref BlobReader sig) + { + if (sig.RemainingBytes >= 4) + { + uint arrayLen = sig.ReadUInt32(); + if (sig.RemainingBytes >= arrayLen) + { + var byteArrayBuilder = ArrayBuilder.GetInstance((int)arrayLen); + for (int i = 0; i < arrayLen; i++) + { + byteArrayBuilder.Add(sig.ReadByte()); + } + + value = byteArrayBuilder.ToImmutableAndFree(); + return true; + } + } + + value = default(ImmutableArray); + return false; + } + internal struct AttributeInfo { public readonly CustomAttributeHandle Handle; @@ -2390,38 +2419,25 @@ internal bool ContainsNoPiaLocalTypes() return _lazyContainsNoPiaLocalTypes == ThreeState.True; } - internal bool HasNullableAttribute(EntityHandle token, out ImmutableArray nullableTransforms) + internal bool HasNullableAttribute(EntityHandle token, out byte defaultTransform, out ImmutableArray nullableTransforms) { AttributeInfo info = FindTargetAttribute(token, AttributeDescription.NullableAttribute); Debug.Assert(!info.HasValue || info.SignatureIndex == 0 || info.SignatureIndex == 1); + defaultTransform = 0; + nullableTransforms = default(ImmutableArray); + if (!info.HasValue) { - nullableTransforms = default(ImmutableArray); return false; } if (info.SignatureIndex == 0) { - nullableTransforms = s_simpleDynamicOrNullableTransforms; - return true; - } - - return TryExtractBoolArrayValueFromAttribute(info.Handle, out nullableTransforms); - } - - internal bool HasNonNullTypesAttribute(EntityHandle token, out bool value) - { - AttributeInfo info = FindTargetAttribute(token, AttributeDescription.NonNullTypesAttribute); - Debug.Assert(!info.HasValue || info.SignatureIndex == 0); - - if (info.HasValue && TryExtractValueFromAttribute(info.Handle, out value, s_attributeBooleanValueExtractor)) - { - return true; + return TryExtractValueFromAttribute(info.Handle, out defaultTransform, s_attributeByteValueExtractor); } - value = false; - return false; + return TryExtractByteArrayValueFromAttribute(info.Handle, out nullableTransforms); } #endregion diff --git a/src/Compilers/Core/Portable/PEWriter/FullMetadataWriter.cs b/src/Compilers/Core/Portable/PEWriter/FullMetadataWriter.cs index 11a684df215f7..7f5ad7afa9c9e 100644 --- a/src/Compilers/Core/Portable/PEWriter/FullMetadataWriter.cs +++ b/src/Compilers/Core/Portable/PEWriter/FullMetadataWriter.cs @@ -325,9 +325,6 @@ internal FullReferenceIndexer(MetadataWriter metadataWriter) : base(metadataWriter) { } - - protected override bool ProcessReferencesInCurrentModule - => false; } protected override void PopulateEncLogTableRows(ImmutableArray rowCounts) diff --git a/src/Compilers/Core/Portable/PEWriter/ReferenceIndexerBase.cs b/src/Compilers/Core/Portable/PEWriter/ReferenceIndexerBase.cs index 71be69f16290e..43017309dfd34 100644 --- a/src/Compilers/Core/Portable/PEWriter/ReferenceIndexerBase.cs +++ b/src/Compilers/Core/Portable/PEWriter/ReferenceIndexerBase.cs @@ -29,7 +29,6 @@ public override void Visit(IAssemblyReference assemblyReference) } protected abstract void RecordAssemblyReference(IAssemblyReference assemblyReference); - protected abstract bool ProcessReferencesInCurrentModule { get; } public override void Visit(ICustomModifier customModifier) { @@ -52,7 +51,7 @@ public override void Visit(IFieldReference fieldReference) } IUnitReference definingUnit = MetadataWriter.GetDefiningUnitReference(fieldReference.GetContainingType(Context), Context); - if (!ProcessReferencesInCurrentModule && definingUnit != null && ReferenceEquals(definingUnit, Context.Module)) + if (definingUnit != null && ReferenceEquals(definingUnit, Context.Module)) { return; } @@ -136,7 +135,7 @@ public override void Visit(IMethodReference methodReference) // an ordinary method def token. We consistently choose to emit a method ref regardless.) IUnitReference definingUnit = MetadataWriter.GetDefiningUnitReference(methodReference.GetContainingType(Context), Context); - if (!ProcessReferencesInCurrentModule && definingUnit != null && ReferenceEquals(definingUnit, Context.Module) && !methodReference.AcceptsExtraArguments) + if (definingUnit != null && ReferenceEquals(definingUnit, Context.Module) && !methodReference.AcceptsExtraArguments) { return; } diff --git a/src/Compilers/Core/Portable/PEWriter/TypeReferenceIndexer.cs b/src/Compilers/Core/Portable/PEWriter/TypeReferenceIndexer.cs index 42ad949762a59..bca033ceaa5c5 100644 --- a/src/Compilers/Core/Portable/PEWriter/TypeReferenceIndexer.cs +++ b/src/Compilers/Core/Portable/PEWriter/TypeReferenceIndexer.cs @@ -8,7 +8,7 @@ namespace Microsoft.Cci /// /// Visitor to force translation of all symbols that will be referred to /// in metadata. Allows us to build the set of types that must be embedded - /// as local types (for NoPia) and the set of injected types that must be embedded (NonNullTypes, Embedded). + /// as local types (for NoPia). /// internal sealed class TypeReferenceIndexer : ReferenceIndexerBase { @@ -17,10 +17,6 @@ internal TypeReferenceIndexer(EmitContext context) { } - // For purpose of detecting any uses of NonNullTypes attribute, we need to process references in current module too. - protected override bool ProcessReferencesInCurrentModule - => true; - public override void Visit(CommonPEModuleBuilder module) { //EDMAURER visit these assembly-level attributes even when producing a module. diff --git a/src/Compilers/Core/Portable/Symbols/Attributes/AttributeDescription.cs b/src/Compilers/Core/Portable/Symbols/Attributes/AttributeDescription.cs index 5214cb0ac3995..9016453928a43 100644 --- a/src/Compilers/Core/Portable/Symbols/Attributes/AttributeDescription.cs +++ b/src/Compilers/Core/Portable/Symbols/Attributes/AttributeDescription.cs @@ -137,6 +137,7 @@ static AttributeDescription() } private static readonly byte[] s_signature_HasThis_Void = new byte[] { (byte)SignatureAttributes.Instance, 0, Void }; + private static readonly byte[] s_signature_HasThis_Void_Byte = new byte[] { (byte)SignatureAttributes.Instance, 1, Void, Byte }; private static readonly byte[] s_signature_HasThis_Void_Int16 = new byte[] { (byte)SignatureAttributes.Instance, 1, Void, Int16 }; private static readonly byte[] s_signature_HasThis_Void_Int32 = new byte[] { (byte)SignatureAttributes.Instance, 1, Void, Int32 }; private static readonly byte[] s_signature_HasThis_Void_UInt32 = new byte[] { (byte)SignatureAttributes.Instance, 1, Void, UInt32 }; @@ -184,6 +185,7 @@ static AttributeDescription() private static readonly byte[] s_signature_HasThis_Void_Type_Int32 = new byte[] { (byte)SignatureAttributes.Instance, 2, Void, TypeHandle, (byte)TypeHandleTarget.SystemType, Int32 }; private static readonly byte[] s_signature_HasThis_Void_SzArray_Boolean = new byte[] { (byte)SignatureAttributes.Instance, 1, Void, SzArray, Boolean }; + private static readonly byte[] s_signature_HasThis_Void_SzArray_Byte = new byte[] { (byte)SignatureAttributes.Instance, 1, Void, SzArray, Byte }; private static readonly byte[] s_signature_HasThis_Void_SzArray_String = new byte[] { (byte)SignatureAttributes.Instance, 1, Void, SzArray, String }; private static readonly byte[] s_signature_HasThis_Void_String_DeprecationType_UInt32 = new byte[] { (byte)SignatureAttributes.Instance, 3, Void, String, TypeHandle, (byte)TypeHandleTarget.DeprecationType, UInt32 }; @@ -405,8 +407,7 @@ static AttributeDescription() s_signature_HasThis_Void_String_DeprecationType_UInt32_String, }; - private static readonly byte[][] s_signaturesOfNullableAttribute = { s_signature_HasThis_Void, s_signature_HasThis_Void_SzArray_Boolean }; - private static readonly byte[][] s_signaturesOfNonNullTypesAttribute = { s_signature_HasThis_Void_Boolean }; + private static readonly byte[][] s_signaturesOfNullableAttribute = { s_signature_HasThis_Void_Byte, s_signature_HasThis_Void_SzArray_Byte }; private static readonly byte[][] s_signaturesOfExperimentalAttribute = { s_signature_HasThis_Void }; private static readonly byte[][] s_signaturesOfExcludeFromCodeCoverageAttribute = { s_signature_HasThis_Void }; @@ -529,7 +530,6 @@ static AttributeDescription() internal static readonly AttributeDescription AssemblyAlgorithmIdAttribute = new AttributeDescription("System.Reflection", "AssemblyAlgorithmIdAttribute", s_signaturesOfAssemblyAlgorithmIdAttribute); internal static readonly AttributeDescription DeprecatedAttribute = new AttributeDescription("Windows.Foundation.Metadata", "DeprecatedAttribute", s_signaturesOfDeprecatedAttribute); internal static readonly AttributeDescription NullableAttribute = new AttributeDescription("System.Runtime.CompilerServices", "NullableAttribute", s_signaturesOfNullableAttribute); - internal static readonly AttributeDescription NonNullTypesAttribute = new AttributeDescription("System.Runtime.CompilerServices", "NonNullTypesAttribute", s_signaturesOfNonNullTypesAttribute); internal static readonly AttributeDescription ExperimentalAttribute = new AttributeDescription("Windows.Foundation.Metadata", "ExperimentalAttribute", s_signaturesOfExperimentalAttribute); internal static readonly AttributeDescription ExcludeFromCodeCoverageAttribute = new AttributeDescription("System.Diagnostics.CodeAnalysis", "ExcludeFromCodeCoverageAttribute", s_signaturesOfExcludeFromCodeCoverageAttribute); } diff --git a/src/Compilers/Core/Portable/WellKnownMember.cs b/src/Compilers/Core/Portable/WellKnownMember.cs index f9721e4f4900d..73efef27a75bd 100644 --- a/src/Compilers/Core/Portable/WellKnownMember.cs +++ b/src/Compilers/Core/Portable/WellKnownMember.cs @@ -419,9 +419,8 @@ internal enum WellKnownMember Microsoft_CodeAnalysis_Runtime_Instrumentation__CreatePayloadForMethodsSpanningSingleFile, Microsoft_CodeAnalysis_Runtime_Instrumentation__CreatePayloadForMethodsSpanningMultipleFiles, - System_Runtime_CompilerServices_NullableAttribute__ctor, + System_Runtime_CompilerServices_NullableAttribute__ctorByte, System_Runtime_CompilerServices_NullableAttribute__ctorTransformFlags, - System_Runtime_CompilerServices_NonNullTypesAttribute__ctor, System_Runtime_CompilerServices_ReferenceAssemblyAttribute__ctor, System_Runtime_CompilerServices_IsReadOnlyAttribute__ctor, System_Runtime_CompilerServices_IsByRefLikeAttribute__ctor, @@ -447,8 +446,6 @@ internal enum WellKnownMember System_Math__FloorDouble, System_Math__TruncateDouble, - Microsoft_CodeAnalysis_EmbeddedAttribute__ctor, - System_Index__ctor, System_Index__FromEnd, System_Index__Value, diff --git a/src/Compilers/Core/Portable/WellKnownMembers.cs b/src/Compilers/Core/Portable/WellKnownMembers.cs index 8c79d97c451b3..801746725818e 100644 --- a/src/Compilers/Core/Portable/WellKnownMembers.cs +++ b/src/Compilers/Core/Portable/WellKnownMembers.cs @@ -2911,12 +2911,13 @@ static WellKnownMembers() (byte)SignatureTypeCode.ByReference, (byte)SignatureTypeCode.SZArray, (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Boolean, (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Int32, - // System_Runtime_CompilerServices_NullableAttribute__ctor + // System_Runtime_CompilerServices_NullableAttribute__ctorByte (byte)MemberFlags.Constructor, // Flags (byte)WellKnownType.ExtSentinel, (byte)(WellKnownType.System_Runtime_CompilerServices_NullableAttribute - WellKnownType.ExtSentinel), // DeclaringTypeId 0, // Arity - 0, // Method Signature + 1, // Method Signature (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Void, + (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Byte, // System_Runtime_CompilerServices_NullableAttribute__ctorTransformFlags (byte)MemberFlags.Constructor, // Flags @@ -2924,15 +2925,7 @@ static WellKnownMembers() 0, // Arity 1, // Method Signature (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Void, - (byte)SignatureTypeCode.SZArray, (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Boolean, - - // System_Runtime_CompilerServices_NonNullTypesAttribute__ctor - (byte)MemberFlags.Constructor, // Flags - (byte)WellKnownType.ExtSentinel, (byte)(WellKnownType.System_Runtime_CompilerServices_NonNullTypesAttribute - WellKnownType.ExtSentinel), // DeclaringTypeId - 0, // Arity - 1, // Method Signature - (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Void, - (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Boolean, + (byte)SignatureTypeCode.SZArray, (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Byte, // System_Runtime_CompilerServices_ReferenceAssemblyAttribute__ctor (byte)MemberFlags.Constructor, // Flags @@ -3075,13 +3068,6 @@ static WellKnownMembers() (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Double, // Return Type (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Double, - // Microsoft_CodeAnalysis_EmbeddedAttribute__ctor - (byte)(MemberFlags.Constructor), // Flags - (byte)WellKnownType.ExtSentinel, (byte)(WellKnownType.Microsoft_CodeAnalysis_EmbeddedAttribute - WellKnownType.ExtSentinel), // DeclaringTypeId - 0, // Arity - 0, // Method Signature - (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Void, // Return Type - // System_Index__ctor (byte)(MemberFlags.Constructor), // Flags (byte)WellKnownType.ExtSentinel, (byte)(WellKnownType.System_Index - WellKnownType.ExtSentinel), // DeclaringTypeId @@ -3677,9 +3663,8 @@ static WellKnownMembers() "CreatePayload", // Microsoft_CodeAnalysis_Runtime_Instrumentation__CreatePayloadForMethodsSpanningSingleFile "CreatePayload", // Microsoft_CodeAnalysis_Runtime_Instrumentation__CreatePayloadForMethodsSpanningMultipleFiles - ".ctor", // System_Runtime_CompilerServices_NullableAttribute__ctor + ".ctor", // System_Runtime_CompilerServices_NullableAttribute__ctorByte ".ctor", // System_Runtime_CompilerServices_NullableAttribute__ctorTransformFlags - ".ctor", // System_Runtime_CompilerServices_NonNullTypesAttribute__ctor ".ctor", // System_Runtime_CompilerServices_ReferenceAssemblyAttribute__ctor ".ctor", // System_Runtime_CompilerServices_IsReadOnlyAttribute__ctor ".ctor", // System_Runtime_CompilerServices_IsByRefLikeAttribute__ctor @@ -3699,7 +3684,6 @@ static WellKnownMembers() "Ceiling", // System_Math__CeilingDouble "Floor", // System_Math__FloorDouble "Truncate", // System_Math__TruncateDouble - ".ctor", // Microsoft_CodeAnalysis_EmbeddedAttribute__ctor ".ctor", // System_Index__ctor "FromEnd", // System_Index__FromEnd diff --git a/src/Compilers/Core/Portable/WellKnownTypes.cs b/src/Compilers/Core/Portable/WellKnownTypes.cs index c3ec1e1e6529d..57d74387f41d3 100644 --- a/src/Compilers/Core/Portable/WellKnownTypes.cs +++ b/src/Compilers/Core/Portable/WellKnownTypes.cs @@ -276,9 +276,6 @@ internal enum WellKnownType System_Runtime_CompilerServices_IsUnmanagedAttribute, Microsoft_VisualBasic_Conversion, - System_Runtime_CompilerServices_NonNullTypesAttribute, - System_AttributeTargets, - Microsoft_CodeAnalysis_EmbeddedAttribute, System_Index, System_Range, @@ -564,9 +561,6 @@ internal static class WellKnownTypes "System.Runtime.CompilerServices.IsUnmanagedAttribute", "Microsoft.VisualBasic.Conversion", - "System.Runtime.CompilerServices.NonNullTypesAttribute", - "System.AttributeTargets", - "Microsoft.CodeAnalysis.EmbeddedAttribute", "System.Index", "System.Range", diff --git a/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs b/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs index 40958cc511e81..c803a6d8c4f4f 100644 --- a/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs +++ b/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs @@ -44,8 +44,8 @@ namespace System.Runtime.CompilerServices AllowMultiple = false)] public class NullableAttribute : Attribute { - public NullableAttribute() { } - public NullableAttribute(bool[] transformFlags) + public NullableAttribute(byte transformFlag) { } + public NullableAttribute(byte[] transformFlags) { } } diff --git a/src/Compilers/VisualBasic/Portable/Emit/PEAssemblyBuilder.vb b/src/Compilers/VisualBasic/Portable/Emit/PEAssemblyBuilder.vb index f16bee519d988..80c0af9ab7fa2 100644 --- a/src/Compilers/VisualBasic/Portable/Emit/PEAssemblyBuilder.vb +++ b/src/Compilers/VisualBasic/Portable/Emit/PEAssemblyBuilder.vb @@ -132,16 +132,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit Return m_SourceAssembly.AssemblyVersionPattern End Get End Property - - Protected Overrides ReadOnly Property InjectedSymbolsAreFrozen As Boolean - Get - Return True - End Get - End Property - - Protected Overrides Function GetInjectedTypes(diagnostics As DiagnosticBag) As ImmutableArray(Of NamedTypeSymbol) - Return ImmutableArray(Of NamedTypeSymbol).Empty - End Function End Class Friend NotInheritable Class PEAssemblyBuilder diff --git a/src/Compilers/VisualBasic/Portable/Emit/PENetModuleBuilder.vb b/src/Compilers/VisualBasic/Portable/Emit/PENetModuleBuilder.vb index dcc857b557c76..473ab9e200e90 100644 --- a/src/Compilers/VisualBasic/Portable/Emit/PENetModuleBuilder.vb +++ b/src/Compilers/VisualBasic/Portable/Emit/PENetModuleBuilder.vb @@ -44,15 +44,5 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit Return Nothing End Get End Property - - Protected Overrides ReadOnly Property InjectedSymbolsAreFrozen As Boolean - Get - Return True - End Get - End Property - - Protected Overrides Function GetInjectedTypes(diagnostics As DiagnosticBag) As ImmutableArray(Of NamedTypeSymbol) - Return ImmutableArray(Of NamedTypeSymbol).Empty - End Function End Class End Namespace diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/WellKnownTypeValidationTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/WellKnownTypeValidationTests.vb index cea713242e75e..b3a4e454fca38 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/WellKnownTypeValidationTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/WellKnownTypeValidationTests.vb @@ -528,10 +528,6 @@ End Namespace WellKnownType.System_Runtime_CompilerServices_IsUnmanagedAttribute ' Not always available. Continue For - Case WellKnownType.System_Runtime_CompilerServices_NonNullTypesAttribute, - WellKnownType.Microsoft_CodeAnalysis_EmbeddedAttribute - ' Injected type - Continue For End Select Dim symbol = comp.GetWellKnownType(wkt) @@ -586,10 +582,6 @@ End Namespace WellKnownType.System_Runtime_CompilerServices_IsUnmanagedAttribute ' Not always available. Continue For - Case WellKnownType.System_Runtime_CompilerServices_NonNullTypesAttribute, - WellKnownType.Microsoft_CodeAnalysis_EmbeddedAttribute - ' Injected type - Continue For End Select Dim symbol = comp.GetWellKnownType(wkt) @@ -623,9 +615,8 @@ End Namespace ' Not a real value. Continue For Case WellKnownMember.System_Array__Empty, - WellKnownMember.System_Runtime_CompilerServices_NullableAttribute__ctor, + WellKnownMember.System_Runtime_CompilerServices_NullableAttribute__ctorByte, WellKnownMember.System_Runtime_CompilerServices_NullableAttribute__ctorTransformFlags, - WellKnownMember.System_Runtime_CompilerServices_NonNullTypesAttribute__ctor, WellKnownMember.System_Span_T__ctor, WellKnownMember.System_Span_T__get_Item, WellKnownMember.System_Span_T__get_Length, @@ -668,9 +659,6 @@ End Namespace WellKnownMember.System_Range__ToEnd ' Not always available. Continue For - Case WellKnownMember.Microsoft_CodeAnalysis_EmbeddedAttribute__ctor - ' Injected type available in VB. - Continue For End Select Dim symbol = comp.GetWellKnownTypeMember(wkm) @@ -750,9 +738,8 @@ End Namespace ' The type is not embedded, so the member is not available. Continue For Case WellKnownMember.System_Array__Empty, - WellKnownMember.System_Runtime_CompilerServices_NullableAttribute__ctor, + WellKnownMember.System_Runtime_CompilerServices_NullableAttribute__ctorByte, WellKnownMember.System_Runtime_CompilerServices_NullableAttribute__ctorTransformFlags, - WellKnownMember.System_Runtime_CompilerServices_NonNullTypesAttribute__ctor, WellKnownMember.System_Span_T__ctor, WellKnownMember.System_Span_T__get_Item, WellKnownMember.System_Span_T__get_Length, @@ -795,9 +782,6 @@ End Namespace WellKnownMember.System_Range__ToEnd ' Not always available. Continue For - Case WellKnownMember.Microsoft_CodeAnalysis_EmbeddedAttribute__ctor - ' Injected type available in VB. - Continue For End Select Dim symbol = comp.GetWellKnownTypeMember(wkm) diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/GenerateType/GenerateTypeTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/GenerateType/GenerateTypeTests.cs index 139b7ffb116cb..42e267d0f3510 100644 --- a/src/EditorFeatures/CSharpTest/Diagnostics/GenerateType/GenerateTypeTests.cs +++ b/src/EditorFeatures/CSharpTest/Diagnostics/GenerateType/GenerateTypeTests.cs @@ -5218,9 +5218,9 @@ void M() internal class Class {{ - private System.Object method; + private global::System.Object method; - public Class(System.Object method) + public Class(global::System.Object method) {{ this.method = method; }} diff --git a/src/EditorFeatures/CSharpTest/GenerateConstructor/GenerateConstructorTests.cs b/src/EditorFeatures/CSharpTest/GenerateConstructor/GenerateConstructorTests.cs index e834a7ddb3140..188f55bceff41 100644 --- a/src/EditorFeatures/CSharpTest/GenerateConstructor/GenerateConstructorTests.cs +++ b/src/EditorFeatures/CSharpTest/GenerateConstructor/GenerateConstructorTests.cs @@ -3466,9 +3466,9 @@ void M() internal class Class {{ - private System.Object method; + private global::System.Object method; - public Class(System.Object method) + public Class(global::System.Object method) {{ this.method = method; }} diff --git a/src/EditorFeatures/CSharpTest/GenerateFromMembers/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersTests.cs b/src/EditorFeatures/CSharpTest/GenerateFromMembers/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersTests.cs index 711b139116fff..7f5f258e2de21 100644 --- a/src/EditorFeatures/CSharpTest/GenerateFromMembers/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersTests.cs +++ b/src/EditorFeatures/CSharpTest/GenerateFromMembers/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersTests.cs @@ -1307,7 +1307,7 @@ public class Class1 { int i; - public override System.Boolean Equals(System.Object obj) + public override global::System.Boolean Equals(global::System.Object obj) { var @class = obj as Class1; return @class != null; @@ -1317,7 +1317,7 @@ public void F() { } - public override System.Int32 GetHashCode() + public override global::System.Int32 GetHashCode() { return 0; } diff --git a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Binders/EEMethodBinder.cs b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Binders/EEMethodBinder.cs index 93a618ee1984b..257d46900e834 100644 --- a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Binders/EEMethodBinder.cs +++ b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Binders/EEMethodBinder.cs @@ -16,7 +16,7 @@ internal sealed class EEMethodBinder : Binder private readonly ImmutableArray _targetParameters; private readonly Binder _sourceBinder; - internal EEMethodBinder(EEMethodSymbol method, MethodSymbol containingMethod, Binder next) : base(next) + internal EEMethodBinder(EEMethodSymbol method, MethodSymbol containingMethod, Binder next) : base(next, next.Flags | BinderFlags.InEEMethodBinder) { // There are a lot of method symbols floating around and we're doing some subtle things with them. // 1) method is the EEMethodSymbol that we're going to synthesize and hand to the debugger to evaluate. diff --git a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/PseudoVariableTests.cs b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/PseudoVariableTests.cs index 1aab31150ae1c..099d5f98a75ff 100644 --- a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/PseudoVariableTests.cs +++ b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/PseudoVariableTests.cs @@ -524,7 +524,7 @@ private void CheckVariable(RuntimeInstance runtime, string variableName, Alias a var testData = Evaluate(runtime, "C.M", variableName, out error, alias); if (valid) { - var expectedNames = new[] { "<>x.<>m0()", "System.Runtime.CompilerServices.NonNullTypesAttribute..ctor(bool)", "Microsoft.CodeAnalysis.EmbeddedAttribute..ctor()" }; + var expectedNames = new[] { "<>x.<>m0()" }; var actualNames = testData.GetMethodsByName().Keys; AssertEx.SetEqual(expectedNames, actualNames); } diff --git a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/ReferencedModulesTests.cs b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/ReferencedModulesTests.cs index 48b9546ba95ac..54781d45588f0 100644 --- a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/ReferencedModulesTests.cs +++ b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/ReferencedModulesTests.cs @@ -1554,17 +1554,10 @@ protected override void AddEmbeddedResourcesFromAddedModules(ArrayBuilder throw ExceptionUtilities.Unreachable; - - protected override void EnsureEmbeddedAttributeExists() - => throw ExceptionUtilities.Unreachable; - - protected override bool InjectedSymbolsAreFrozen - => true; - - protected override ImmutableArray GetInjectedTypes(DiagnosticBag diagnostics) - => ImmutableArray.Empty; + internal override SynthesizedAttributeData SynthesizeEmbeddedAttribute() + { + throw new NotImplementedException(); + } AssemblyIdentity IAssemblyReference.Identity => ((IAssemblyReference)_builder).Identity; diff --git a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/UsingDebugInfoTests.cs b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/UsingDebugInfoTests.cs index 2fef480d002b2..0edfb722246a9 100644 --- a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/UsingDebugInfoTests.cs +++ b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/UsingDebugInfoTests.cs @@ -651,7 +651,7 @@ int M() var actualNamespace = imports.Usings.Single().NamespaceOrType; Assert.Equal(SymbolKind.Namespace, actualNamespace.Kind); - Assert.Equal(NamespaceKind.Compilation, ((NamespaceSymbol)actualNamespace).Extent.Kind); + Assert.Equal(NamespaceKind.Module, ((NamespaceSymbol)actualNamespace).Extent.Kind); Assert.Equal("System", actualNamespace.ToTestDisplayString()); }); } @@ -692,7 +692,7 @@ int M() { var actualNamespace = usings[i]; Assert.Equal(SymbolKind.Namespace, actualNamespace.Kind); - Assert.Equal(actualNamespace.Name == "System" ? NamespaceKind.Compilation : NamespaceKind.Module, ((NamespaceSymbol)actualNamespace).Extent.Kind); + Assert.Equal(NamespaceKind.Module, ((NamespaceSymbol)actualNamespace).Extent.Kind); Assert.Equal(expectedNames[i], actualNamespace.ToTestDisplayString()); } }); @@ -735,7 +735,7 @@ int M() var actualNamespace = imports.Usings.Single().NamespaceOrType; Assert.Equal(SymbolKind.Namespace, actualNamespace.Kind); - Assert.Equal(actualNamespace.Name == "System" ? NamespaceKind.Compilation : NamespaceKind.Module, ((NamespaceSymbol)actualNamespace).Extent.Kind); + Assert.Equal(NamespaceKind.Module, ((NamespaceSymbol)actualNamespace).Extent.Kind); Assert.Equal(expectedNames[i], actualNamespace.ToTestDisplayString()); } }); @@ -777,7 +777,7 @@ int M() var namespaceSymbol = aliasSymbol.Target; Assert.Equal(SymbolKind.Namespace, namespaceSymbol.Kind); - Assert.Equal(NamespaceKind.Compilation, ((NamespaceSymbol)namespaceSymbol).Extent.Kind); + Assert.Equal(NamespaceKind.Module, ((NamespaceSymbol)namespaceSymbol).Extent.Kind); Assert.Equal("System", namespaceSymbol.ToTestDisplayString()); }); } diff --git a/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/ReferencedModulesTests.vb b/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/ReferencedModulesTests.vb index f7dd1b286520a..68a9aa11da629 100644 --- a/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/ReferencedModulesTests.vb +++ b/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/ReferencedModulesTests.vb @@ -997,16 +997,6 @@ End Class" Return DirectCast(_builder, IAssemblyReference).AssemblyVersionPattern End Get End Property - - Protected Overrides ReadOnly Property InjectedSymbolsAreFrozen As Boolean - Get - Return True - End Get - End Property - - Protected Overrides Function GetInjectedTypes(diagnostics As DiagnosticBag) As ImmutableArray(Of NamedTypeSymbol) - Return ImmutableArray(Of NamedTypeSymbol).Empty - End Function End Class End Class diff --git a/src/Scripting/CSharpTest/InteractiveSessionTests.cs b/src/Scripting/CSharpTest/InteractiveSessionTests.cs index e21074d39f40e..6c4c7766067ee 100644 --- a/src/Scripting/CSharpTest/InteractiveSessionTests.cs +++ b/src/Scripting/CSharpTest/InteractiveSessionTests.cs @@ -1598,9 +1598,9 @@ public void HostObjectAssemblyReference1() globalsType: typeof(CommandLineScriptGlobals)).GetCompilation(); scriptCompilation.VerifyDiagnostics( - // (1,8): error CS0234: The type or namespace name 'Scripting' does not exist in the namespace 'Microsoft.CodeAnalysis' (are you missing an assembly reference?) + // (1,8): error CS0234: The type or namespace name 'CodeAnalysis' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?) // nameof(Microsoft.CodeAnalysis.Scripting) - Diagnostic(ErrorCode.ERR_DottedTypeNameNotFoundInNS, "Microsoft.CodeAnalysis.Scripting").WithArguments("Scripting", "Microsoft.CodeAnalysis").WithLocation(1, 8)); + Diagnostic(ErrorCode.ERR_DottedTypeNameNotFoundInNS, "Microsoft.CodeAnalysis").WithArguments("CodeAnalysis", "Microsoft").WithLocation(1, 8)); string corAssemblyName = typeof(object).GetTypeInfo().Assembly.GetName().Name; string hostObjectAssemblyName = scriptCompilation.ScriptCompilationInfo.GlobalsType.GetTypeInfo().Assembly.GetName().Name; diff --git a/src/Test/Utilities/Portable/Metadata/MetadataReaderUtils.cs b/src/Test/Utilities/Portable/Metadata/MetadataReaderUtils.cs index 5d6fb510a28a3..f638e6f345e8e 100644 --- a/src/Test/Utilities/Portable/Metadata/MetadataReaderUtils.cs +++ b/src/Test/Utilities/Portable/Metadata/MetadataReaderUtils.cs @@ -181,9 +181,9 @@ private static ImmutableArray ReadArray(this MetadataReader reader, BlobHa return builder.ToImmutableAndFree(); } - public static ImmutableArray ReadBoolArray(this MetadataReader reader, BlobHandle blobHandle) + public static ImmutableArray ReadByteArray(this MetadataReader reader, BlobHandle blobHandle) { - return ReadArray(reader, blobHandle, (ref BlobReader blobReader) => blobReader.ReadBoolean()); + return ReadArray(reader, blobHandle, (ref BlobReader blobReader) => blobReader.ReadByte()); } public static IEnumerable GetCustomAttributeRows(this MetadataReader reader) diff --git a/src/Workspaces/CoreTest/SymbolKeyTests.cs b/src/Workspaces/CoreTest/SymbolKeyTests.cs index baeb657d1e74d..5914b72f1dee5 100644 --- a/src/Workspaces/CoreTest/SymbolKeyTests.cs +++ b/src/Workspaces/CoreTest/SymbolKeyTests.cs @@ -77,13 +77,8 @@ namespace A { namespace N { } } "; var compilation = GetCompilation(source, LanguageNames.CSharp); var symbols = GetDeclaredSymbols(compilation); - Assert.Equal(14, symbols.Count()); - Assert.Equal(new[] { "N", "A", "A.B", "A.B.C", "A.N", - "Microsoft", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.EmbeddedAttribute", - "Microsoft.CodeAnalysis.EmbeddedAttribute.EmbeddedAttribute()", - "System", "System.Runtime", "System.Runtime.CompilerServices", - "System.Runtime.CompilerServices.NonNullTypesAttribute", - "System.Runtime.CompilerServices.NonNullTypesAttribute.NonNullTypesAttribute(bool)" }, + Assert.Equal(5, symbols.Count()); + Assert.Equal(new[] { "N", "A", "A.B", "A.B.C", "A.N" }, symbols.Select(s => s.ToDisplayString())); TestRoundTrip(symbols, compilation); } From 89ad74c2331754793dcd78ff9fc5e93ff3de081a Mon Sep 17 00:00:00 2001 From: AlekseyTs Date: Thu, 15 Nov 2018 10:05:00 -0800 Subject: [PATCH 2/5] Follow-up on merge from dev16.0-preview2 --- .../Test/Semantic/Semantics/NullableReferenceTypesTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs index fc22dc304d3a6..18d22d127397b 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs @@ -27436,7 +27436,7 @@ class D { void M(C c) { - c.M() /*T:System.Collections.Generic.IEnumerable!*/ ; + c.M() /*T:System.Collections.Generic.IEnumerable!*/ ; c.M2() /*T:System.Collections.Generic.IEnumerable!*/ ; } } From 60ce669d6d2b30ba370941c4b3a5709bae3cbd6c Mon Sep 17 00:00:00 2001 From: AlekseyTs Date: Thu, 15 Nov 2018 16:45:52 -0800 Subject: [PATCH 3/5] Tests, adjustments, speclet update. --- docs/features/nullable-reference-types.md | 71 ++- .../Portable/Emitter/Model/PEModuleBuilder.cs | 1 + .../SymbolDisplayVisitor.Types.cs | 2 +- .../Symbols/TypeSymbolWithAnnotations.cs | 8 +- .../Semantics/NullableReferenceTypesTests.cs | 434 +++++++++++++++++- 5 files changed, 470 insertions(+), 46 deletions(-) diff --git a/docs/features/nullable-reference-types.md b/docs/features/nullable-reference-types.md index d9ceb402e2584..f10602d5e676e 100644 --- a/docs/features/nullable-reference-types.md +++ b/docs/features/nullable-reference-types.md @@ -8,7 +8,7 @@ In source, nullable reference types are annotated with `?`. string? OptString; // may be null Dictionary? OptDictionaryOptValues; // dictionary may be null, values may be null ``` -A warning is reported when annotating a reference type or unconstrained generic type with `?` outside a `NonNullTypes(true)` context. +A warning is reported when annotating a reference type or unconstrained generic type with `?` outside a `#nullable` context. In metadata, nullable reference types are annotated with a `[Nullable]` attribute. ```c# @@ -22,54 +22,43 @@ namespace System.Runtime.CompilerServices AllowMultiple = false)] public sealed class NullableAttribute : Attribute { - public NullableAttribute() { } - public NullableAttribute(bool[] b) { } + public NullableAttribute(byte b) { } + public NullableAttribute(byte[] b) { } } } ``` -The parameter-less constructor is emitted for simple type references with top-level nullability and for type parameter definitions that have a `class?` constraint; -the constructor with `bool[]` parameter is emitted for type references with nested types and nullability. + +Each type reference is accompanied by a NullableAttribute with an array of bytes, where 0 is Oblivious, 1 is NotAnnotated and 2 is Annotated. + +To optimize trivial cases the attribute can be omitted, or instead can be replaced with an attribute that takes a single byte value rather than an array. + +Trivial/optimized cases: +1) All parts are NotAnnotated – a NullableAttribute with a single value 1 (rather than an array of 1s) +2) All parts are Annotated - a NullableAttribute with a single value 2 (rather than an array of 2s) +3) All parts are Oblivious – the attribute is omitted, this matches how we interpret the lack of an attribute in legacy assemblies. + For completeness, we would also recognize a NullableAttribute with a single value 0 (rather than an array of 0s), + but compiler will never emit an attribute like this. + +NullableAttribute(1) should be placed on a type parameter definition that has a `class!` constraint. +NullableAttribute(2) should be placed on a type parameter definition that has a `class?` constraint. +Other forms of NullableAttribute ar not emitted on type parameter definitions and are not specially recognized on them. + +The `NullableAttribute` type declaration is synthesized by the compiler if it is not included in the compilation, but is needed to produce the output. + ```c# // C# representation of metadata -[Nullable] +[Nullable(2)] string OptString; // string? -[Nullable(new[] { true, false, true })] +[Nullable(new[] { 2, 1, 2 })] Dictionary OptDictionaryOptValues; // Dictionary? +string[] Oblivious1; // string~[]~ +[Nullable(0)] string[] Oblivious2; // string~[]~ +[Nullable(new[] { 0, 0 })] string[] Oblivious3; // string~[]~ +[Nullable(1)] string[] NotNull1; // string![]! +[Nullable(new[] { 1, 1 })] string[] NotNull2; // string![]! +[Nullable(new[] { 0, 2 })] string[] ObliviousMaybeNull; // string?[]~ +[Nullable(new[] { 1, 2 })] string[] NotNullMaybeNull; // string?[]! ``` -The `NullableAttribute` type declaration is synthesized by the compiler if it is not included in the compilation. - -Unannotated reference types are non-nullable or null-oblivious depending on whether the containing scope includes `[NonNullTypes]`. -```c# -namespace System.Runtime.CompilerServices -{ - [AttributeUsage(AttributeTargets.Class | - AttributeTargets.Constructor | - AttributeTargets.Delegate | - AttributeTargets.Enum | - AttributeTargets.Event | - AttributeTargets.Field | - AttributeTargets.Interface | - AttributeTargets.Method | - AttributeTargets.Module | - AttributeTargets.Property | - AttributeTargets.Struct, - AllowMultiple = false)] - internal sealed class NonNullTypesAttribute : Attribute - { - public NonNullTypesAttribute(bool enabled = true) { } - } -} -``` -If there is no `[NonNullTypes]` attribute at any containing scope, including the module, reference types are null-oblivious. -```c# -[NonNullTypes(false)] string[] Oblivious; // string~[]~ -[NonNullTypes(true)] string[] NotNull; // string![]! -[NonNullTypes(false), Nullable(new[] { false, true })] string[] ObliviousMaybeNull; // string?[]~ -[NonNullTypes(true), Nullable(new[] { false, true })] string[] NotNullMaybeNull; // string?[]! -``` -The `NonNullTypesAttribute` is always implicitly included in a compilation, but is only emitted if it is referenced in source. It cannot be referenced from metadata (assembly or module). -`NonNullTypesAttribute` can only be used in C# 8.0 compilations (or above). - ## Declaration warnings _Describe warnings reported for declarations in initial binding._ diff --git a/src/Compilers/CSharp/Portable/Emitter/Model/PEModuleBuilder.cs b/src/Compilers/CSharp/Portable/Emitter/Model/PEModuleBuilder.cs index 39b55bc2f07cb..6dc50683e4f86 100644 --- a/src/Compilers/CSharp/Portable/Emitter/Model/PEModuleBuilder.cs +++ b/src/Compilers/CSharp/Portable/Emitter/Model/PEModuleBuilder.cs @@ -1515,6 +1515,7 @@ internal SynthesizedAttributeData SynthesizeNullableAttribute(Symbol symbol, Typ foreach (byte flag in flagsBuilder) { + Debug.Assert(flag == (byte)NullableAnnotation.Unknown || flag == (byte)NullableAnnotation.NotNullable || flag == (byte)NullableAnnotation.Nullable); constantsBuilder.Add(new TypedConstant(byteType, TypedConstantKind.Primitive, flag)); } diff --git a/src/Compilers/CSharp/Portable/SymbolDisplay/SymbolDisplayVisitor.Types.cs b/src/Compilers/CSharp/Portable/SymbolDisplay/SymbolDisplayVisitor.Types.cs index 7c161543f7774..0d5c6d965979c 100644 --- a/src/Compilers/CSharp/Portable/SymbolDisplay/SymbolDisplayVisitor.Types.cs +++ b/src/Compilers/CSharp/Portable/SymbolDisplay/SymbolDisplayVisitor.Types.cs @@ -98,7 +98,7 @@ private void AddNullableAnnotations(TypeSymbolWithAnnotations typeOpt) } if (format.MiscellaneousOptions.IncludesOption(SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier) && - !typeOpt.IsNullableType() && + !typeOpt.IsNullableType() && !typeOpt.IsValueType && (typeOpt.NullableAnnotation == NullableAnnotation.Nullable || (typeOpt.NullableAnnotation == NullableAnnotation.NullableBasedOnAnalysis && !typeOpt.TypeSymbol.IsUnconstrainedTypeParameter()))) { diff --git a/src/Compilers/CSharp/Portable/Symbols/TypeSymbolWithAnnotations.cs b/src/Compilers/CSharp/Portable/Symbols/TypeSymbolWithAnnotations.cs index e0e492c5f55f5..e36b3278a5956 100644 --- a/src/Compilers/CSharp/Portable/Symbols/TypeSymbolWithAnnotations.cs +++ b/src/Compilers/CSharp/Portable/Symbols/TypeSymbolWithAnnotations.cs @@ -506,7 +506,7 @@ public string ToDisplayString(SymbolDisplayFormat format = null) if (format != null) { if (format.MiscellaneousOptions.IncludesOption(SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier) && - !IsNullableType() && + !IsNullableType() && !IsValueType && (NullableAnnotation == NullableAnnotation.Nullable || (NullableAnnotation == NullableAnnotation.NullableBasedOnAnalysis && !TypeSymbol.IsUnconstrainedTypeParameter()))) { @@ -833,13 +833,17 @@ public bool ApplyNullableTransforms(byte defaultTransformFlag, ImmutableArray(TM1 x) where TM1 : class", m1.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + TypeParameterSymbol tm1 = m1.TypeParameters[0]; + Assert.Null(tm1.ReferenceTypeConstraintIsNullable); + Assert.Empty(tm1.GetAttributes()); + } } [Fact] @@ -55292,6 +55299,429 @@ static void M(object x) Diagnostic(ErrorCode.ERR_ObjectProhibited, "c2.F").WithArguments("C.F()").WithLocation(14, 9)); } + [Fact] + public void AnnotationsInMetadata_01() + { + var source = +@" +using System.Collections.Generic; + +class B +{ + public int F01; + public int? F02; + public string F03; + public string? F04; + public KeyValuePair F05; + public KeyValuePair F06; + public KeyValuePair F07; + public KeyValuePair F08; + public KeyValuePair F09; + public KeyValuePair F10; + public KeyValuePair F11; + public KeyValuePair F12; + public KeyValuePair F13; + public Dictionary F14; + public Dictionary? F15; + public Dictionary F16; + public Dictionary? F17; + public Dictionary F18; + public Dictionary? F19; + public Dictionary F20; + public Dictionary? F21; + public Dictionary F22; + public Dictionary? F23; + public Dictionary F24; + public Dictionary? F25; + public Dictionary F26; + public Dictionary? F27; + public Dictionary F28; + public Dictionary? F29; + public Dictionary F30; + public Dictionary? F31; +} +"; + var comp1 = CreateCompilation(new[] { source }); + CompileAndVerify(comp1, symbolValidator: + (ModuleSymbol m) => + { + (string type, string attribute)[] baseline = new[] + { + ("System.Int32", null), + ("System.Int32?", null), + ("System.String", null), + ("System.String?", "System.Runtime.CompilerServices.NullableAttribute(2)"), + ("System.Collections.Generic.KeyValuePair", null), + ("System.Collections.Generic.KeyValuePair", null), + ("System.Collections.Generic.KeyValuePair", "System.Runtime.CompilerServices.NullableAttribute({0, 2, 0})"), + ("System.Collections.Generic.KeyValuePair", "System.Runtime.CompilerServices.NullableAttribute({0, 0, 2})"), + ("System.Collections.Generic.KeyValuePair", "System.Runtime.CompilerServices.NullableAttribute({0, 2, 2})"), + ("System.Collections.Generic.KeyValuePair", null), + ("System.Collections.Generic.KeyValuePair", "System.Runtime.CompilerServices.NullableAttribute({0, 0, 2})"), + ("System.Collections.Generic.KeyValuePair", null), + ("System.Collections.Generic.KeyValuePair", "System.Runtime.CompilerServices.NullableAttribute({0, 2, 0})"), + ("System.Collections.Generic.Dictionary", null), + ("System.Collections.Generic.Dictionary?", "System.Runtime.CompilerServices.NullableAttribute({2, 0, 0})"), + ("System.Collections.Generic.Dictionary", null), + ("System.Collections.Generic.Dictionary?", "System.Runtime.CompilerServices.NullableAttribute({2, 0, 0})"), + ("System.Collections.Generic.Dictionary", "System.Runtime.CompilerServices.NullableAttribute({0, 2, 0})"), + ("System.Collections.Generic.Dictionary?", "System.Runtime.CompilerServices.NullableAttribute({2, 2, 0})"), + ("System.Collections.Generic.Dictionary", "System.Runtime.CompilerServices.NullableAttribute({0, 0, 2})"), + ("System.Collections.Generic.Dictionary?", "System.Runtime.CompilerServices.NullableAttribute({2, 0, 2})"), + ("System.Collections.Generic.Dictionary", "System.Runtime.CompilerServices.NullableAttribute({0, 2, 2})"), + ("System.Collections.Generic.Dictionary?", "System.Runtime.CompilerServices.NullableAttribute(2)"), + ("System.Collections.Generic.Dictionary", null), + ("System.Collections.Generic.Dictionary?", "System.Runtime.CompilerServices.NullableAttribute({2, 0, 0})"), + ("System.Collections.Generic.Dictionary", "System.Runtime.CompilerServices.NullableAttribute({0, 0, 2})"), + ("System.Collections.Generic.Dictionary?", "System.Runtime.CompilerServices.NullableAttribute({2, 0, 2})"), + ("System.Collections.Generic.Dictionary", null), + ("System.Collections.Generic.Dictionary?", "System.Runtime.CompilerServices.NullableAttribute({2, 0, 0})"), + ("System.Collections.Generic.Dictionary", "System.Runtime.CompilerServices.NullableAttribute({0, 2, 0})"), + ("System.Collections.Generic.Dictionary?", "System.Runtime.CompilerServices.NullableAttribute({2, 2, 0})") + }; + + Assert.Equal(31, baseline.Length); + AnnotationsInMetadataFieldSymbolValidator(m, baseline); + }); + + var comp2 = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue()); + CompileAndVerify(comp2, symbolValidator: + (ModuleSymbol m) => + { + (string type, string attribute)[] baseline = new[] + { + ("System.Int32", null), + ("System.Int32?", null), + ("System.String!", "System.Runtime.CompilerServices.NullableAttribute(1)"), + ("System.String?", "System.Runtime.CompilerServices.NullableAttribute(2)"), + ("System.Collections.Generic.KeyValuePair", null), + ("System.Collections.Generic.KeyValuePair", "System.Runtime.CompilerServices.NullableAttribute({0, 1, 1})"), + ("System.Collections.Generic.KeyValuePair", "System.Runtime.CompilerServices.NullableAttribute({0, 2, 1})"), + ("System.Collections.Generic.KeyValuePair", "System.Runtime.CompilerServices.NullableAttribute({0, 1, 2})"), + ("System.Collections.Generic.KeyValuePair", "System.Runtime.CompilerServices.NullableAttribute({0, 2, 2})"), + ("System.Collections.Generic.KeyValuePair", "System.Runtime.CompilerServices.NullableAttribute({0, 0, 1})"), + ("System.Collections.Generic.KeyValuePair", "System.Runtime.CompilerServices.NullableAttribute({0, 0, 2})"), + ("System.Collections.Generic.KeyValuePair", "System.Runtime.CompilerServices.NullableAttribute({0, 1, 0})"), + ("System.Collections.Generic.KeyValuePair", "System.Runtime.CompilerServices.NullableAttribute({0, 2, 0})"), + ("System.Collections.Generic.Dictionary!", "System.Runtime.CompilerServices.NullableAttribute({1, 0, 0})"), + ("System.Collections.Generic.Dictionary?", "System.Runtime.CompilerServices.NullableAttribute({2, 0, 0})"), + ("System.Collections.Generic.Dictionary!", "System.Runtime.CompilerServices.NullableAttribute(1)"), + ("System.Collections.Generic.Dictionary?", "System.Runtime.CompilerServices.NullableAttribute({2, 1, 1})"), + ("System.Collections.Generic.Dictionary!", "System.Runtime.CompilerServices.NullableAttribute({1, 2, 1})"), + ("System.Collections.Generic.Dictionary?", "System.Runtime.CompilerServices.NullableAttribute({2, 2, 1})"), + ("System.Collections.Generic.Dictionary!", "System.Runtime.CompilerServices.NullableAttribute({1, 1, 2})"), + ("System.Collections.Generic.Dictionary?", "System.Runtime.CompilerServices.NullableAttribute({2, 1, 2})"), + ("System.Collections.Generic.Dictionary!", "System.Runtime.CompilerServices.NullableAttribute({1, 2, 2})"), + ("System.Collections.Generic.Dictionary?", "System.Runtime.CompilerServices.NullableAttribute(2)"), + ("System.Collections.Generic.Dictionary!", "System.Runtime.CompilerServices.NullableAttribute({1, 0, 1})"), + ("System.Collections.Generic.Dictionary?", "System.Runtime.CompilerServices.NullableAttribute({2, 0, 1})"), + ("System.Collections.Generic.Dictionary!", "System.Runtime.CompilerServices.NullableAttribute({1, 0, 2})"), + ("System.Collections.Generic.Dictionary?", "System.Runtime.CompilerServices.NullableAttribute({2, 0, 2})"), + ("System.Collections.Generic.Dictionary!", "System.Runtime.CompilerServices.NullableAttribute({1, 1, 0})"), + ("System.Collections.Generic.Dictionary?", "System.Runtime.CompilerServices.NullableAttribute({2, 1, 0})"), + ("System.Collections.Generic.Dictionary!", "System.Runtime.CompilerServices.NullableAttribute({1, 2, 0})"), + ("System.Collections.Generic.Dictionary?", "System.Runtime.CompilerServices.NullableAttribute({2, 2, 0})") + }; + + Assert.Equal(31, baseline.Length); + AnnotationsInMetadataFieldSymbolValidator(m, baseline); + }); + } + + private static void AnnotationsInMetadataFieldSymbolValidator(ModuleSymbol m, (string type, string attribute)[] baseline) + { + var b = m.GlobalNamespace.GetMember("B"); + + for (int i = 0; i < baseline.Length; i++) + { + var name = "F" + (i + 1).ToString("00"); + var f = b.GetMember(name); + Assert.Equal(baseline[i].type, f.Type.ToTestDisplayString(true)); + + if (baseline[i].attribute == null) + { + Assert.Empty(f.GetAttributes()); + } + else + { + Assert.Equal(baseline[i].attribute, f.GetAttributes().Single().ToString()); + } + } + } + + [Fact] + public void AnnotationsInMetadata_02() + { + var ilSource = @" +// =============== CLASS MEMBERS DECLARATION =================== + +.class private auto ansi beforefieldinit B`12 + extends [mscorlib]System.Object +{ + .param type T01 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + .param type T02 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param type T03 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .param type T04 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 03 00 00 ) + .param type T05 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 04 00 00 ) + .param type T06 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 05 00 00 ) + .param type T07 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 01 00 00 00 00 00 00 ) + .param type T08 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 01 00 00 00 01 00 00 ) + .param type T09 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 01 00 00 00 02 00 00 ) + .param type T10 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 02 00 00 00 01 01 00 00 ) + .param type T11 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 00 00 00 00 00 00 ) + .param type T12 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 FF FF FF FF 00 00 ) + .field public int32 F01 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + .field public int32 F02 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .field public int32 F03 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .field public int32 F04 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 03 00 00 ) + .field public int32 F05 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 01 00 00 00 00 00 00 ) + .field public int32 F06 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 01 00 00 00 01 00 00 ) + .field public int32 F07 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 01 00 00 00 02 00 00 ) + .field public int32 F08 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 01 00 00 00 04 00 00 ) + .field public int32 F09 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 FF FF FF FF 00 00 ) + .field public valuetype [mscorlib]System.Nullable`1 F10 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + .field public valuetype [mscorlib]System.Nullable`1 F11 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 02 00 00 00 00 00 00 00 ) + .field public valuetype [mscorlib]System.Nullable`1 F12 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 FF FF FF FF 00 00 ) + .field public string F13 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + .field public string F14 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 03 00 00 ) + .field public string F15 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 01 00 00 00 00 00 00 ) + .field public string F16 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 01 00 00 00 01 00 00 ) + .field public string F17 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 01 00 00 00 02 00 00 ) + .field public string F18 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 01 00 00 00 04 00 00 ) + .field public string F19 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 FF FF FF FF 00 00 ) + .field public class [mscorlib]System.Collections.Generic.Dictionary`2 F20 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + .field public class [mscorlib]System.Collections.Generic.Dictionary`2 F21 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 03 00 00 ) + .field public class [mscorlib]System.Collections.Generic.Dictionary`2 F22 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 FF FF FF FF 00 00 ) + .field public class [mscorlib]System.Collections.Generic.Dictionary`2 F23 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 00 00 00 00 00 ) + .field public class [mscorlib]System.Collections.Generic.Dictionary`2 F24 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 01 01 01 00 00 ) + .field public class [mscorlib]System.Collections.Generic.Dictionary`2 F25 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 02 02 02 00 00 ) + .field public class [mscorlib]System.Collections.Generic.Dictionary`2 F26 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 01 04 05 00 00 ) + .field public class [mscorlib]System.Collections.Generic.Dictionary`2 F27 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 00 01 02 00 00 ) + .field public class [mscorlib]System.Collections.Generic.Dictionary`2 F28 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 01 02 00 00 00 ) + .field public class [mscorlib]System.Collections.Generic.Dictionary`2 F29 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 02 00 01 00 00 ) + .field public string F30 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 02 00 00 00 01 01 00 00 ) + .field public string F31 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 00 00 00 00 00 00 ) + .field public class [mscorlib]System.Collections.Generic.Dictionary`2 F32 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 04 00 00 00 01 01 01 01 00 00 ) + .field public class [mscorlib]System.Collections.Generic.Dictionary`2 F33 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 02 00 00 00 01 01 00 00 ) + .field public class [mscorlib]System.Collections.Generic.Dictionary`2 F34 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 00 00 00 00 00 00 ) + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: nop + IL_0007: ret + } // end of method B`12::.ctor + +} // end of class B`12 + +.class public auto ansi beforefieldinit System.Runtime.CompilerServices.NullableAttribute + extends [mscorlib]System.Attribute +{ + .method public hidebysig specialname rtspecialname + instance void .ctor(uint8 x) cil managed + { + // Code size 9 (0x9) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Attribute::.ctor() + IL_0006: nop + IL_0007: nop + IL_0008: ret + } // end of method NullableAttribute::.ctor + + .method public hidebysig specialname rtspecialname + instance void .ctor(uint8[] x) cil managed + { + // Code size 9 (0x9) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Attribute::.ctor() + IL_0006: nop + IL_0007: nop + IL_0008: ret + } // end of method NullableAttribute::.ctor + +} // end of class System.Runtime.CompilerServices.NullableAttribute + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** +/* +class B<[Nullable(0)]T01, + [Nullable(1)]T02, + [Nullable(2)]T03, + [Nullable(3)]T04, + [Nullable(4)]T05, + [Nullable(5)]T06, + [Nullable(new byte[] { 0 })]T07, + [Nullable(new byte[] { 1 })]T08, + [Nullable(new byte[] { 2 })]T09, + [Nullable(new byte[] { 1, 1 })]T10, + [Nullable(new byte[] { })]T11, + [Nullable(null)]T12> + where T01 : class where T02 : class where T03 : class where T04 : class where T05 : class where T06 : class + where T07 : class where T08 : class where T09 : class where T10 : class where T11 : class where T12 : class +{ + [Nullable(0)] public int F01; + [Nullable(1)] public int F02; + [Nullable(2)] public int F03; + [Nullable(3)] public int F04; + [Nullable(new byte[] { 0 })] public int F05; + [Nullable(new byte[] { 1 })] public int F06; + [Nullable(new byte[] { 2 })] public int F07; + [Nullable(new byte[] { 4 })] public int F08; + [Nullable(null)] public int F09; + [Nullable(0)] public int? F10; + [Nullable(new byte[] { 0, 0 })] public int? F11; + [Nullable(null)] public int? F12; + [Nullable(0)] public string F13; + [Nullable(3)] public string F14; + [Nullable(new byte[] { 0 })] public string F15; + [Nullable(new byte[] { 1 })] public string F16; + [Nullable(new byte[] { 2 })] public string F17; + [Nullable(new byte[] { 4 })] public string F18; + [Nullable(null)] public string F19; + [Nullable(0)] public System.Collections.Generic.Dictionary F20; + [Nullable(3)] public System.Collections.Generic.Dictionary F21; + [Nullable(null)] public System.Collections.Generic.Dictionary F22; + [Nullable(new byte[] { 0, 0, 0 })] public System.Collections.Generic.Dictionary F23; + [Nullable(new byte[] { 1, 1, 1 })] public System.Collections.Generic.Dictionary F24; + [Nullable(new byte[] { 2, 2, 2 })] public System.Collections.Generic.Dictionary F25; + [Nullable(new byte[] { 1, 4, 5 })] public System.Collections.Generic.Dictionary F26; + [Nullable(new byte[] { 0, 1, 2 })] public System.Collections.Generic.Dictionary F27; + [Nullable(new byte[] { 1, 2, 0 })] public System.Collections.Generic.Dictionary F28; + [Nullable(new byte[] { 2, 0, 1 })] public System.Collections.Generic.Dictionary F29; + [Nullable(new byte[] { 1, 1 })] public string F30; + [Nullable(new byte[] { })] public string F31; + [Nullable(new byte[] { 1, 1, 1, 1 })] public System.Collections.Generic.Dictionary F32; + [Nullable(new byte[] { 1, 1 })] public System.Collections.Generic.Dictionary F33; + [Nullable(new byte[] { })] public System.Collections.Generic.Dictionary F34; +}*/ +"; + + var source = @""; + var compilation = CreateCompilation(new[] { source }, new[] { CompileIL(ilSource) }); + NamedTypeSymbol b = compilation.GetTypeByMetadataName("B`12"); + + (string type, string attribute)[] fieldsBaseline = new[] + { + ("System.Int32", "System.Runtime.CompilerServices.NullableAttribute(0)"), + ("System.Int32", "System.Runtime.CompilerServices.NullableAttribute(1)"), + ("System.Int32", "System.Runtime.CompilerServices.NullableAttribute(2)"), + ("System.Int32", "System.Runtime.CompilerServices.NullableAttribute(3)"), + ("System.Int32", "System.Runtime.CompilerServices.NullableAttribute({0})"), + ("System.Int32", "System.Runtime.CompilerServices.NullableAttribute({1})"), + ("System.Int32", "System.Runtime.CompilerServices.NullableAttribute({2})"), + ("System.Int32", "System.Runtime.CompilerServices.NullableAttribute({4})"), + ("System.Int32", "System.Runtime.CompilerServices.NullableAttribute(null)"), + ("System.Int32?", "System.Runtime.CompilerServices.NullableAttribute(0)"), + ("System.Int32?", "System.Runtime.CompilerServices.NullableAttribute({0, 0})"), + ("System.Int32?", "System.Runtime.CompilerServices.NullableAttribute(null)"), + ("System.String", "System.Runtime.CompilerServices.NullableAttribute(0)"), + ("System.String", "System.Runtime.CompilerServices.NullableAttribute(3)"), + ("System.String", "System.Runtime.CompilerServices.NullableAttribute({0})"), + ("System.String!", "System.Runtime.CompilerServices.NullableAttribute({1})"), + ("System.String?", "System.Runtime.CompilerServices.NullableAttribute({2})"), + ("System.String", "System.Runtime.CompilerServices.NullableAttribute({4})"), + ("System.String", "System.Runtime.CompilerServices.NullableAttribute(null)"), + ("System.Collections.Generic.Dictionary", "System.Runtime.CompilerServices.NullableAttribute(0)"), + ("System.Collections.Generic.Dictionary", "System.Runtime.CompilerServices.NullableAttribute(3)"), + ("System.Collections.Generic.Dictionary", "System.Runtime.CompilerServices.NullableAttribute(null)"), + ("System.Collections.Generic.Dictionary", "System.Runtime.CompilerServices.NullableAttribute({0, 0, 0})"), + ("System.Collections.Generic.Dictionary!", "System.Runtime.CompilerServices.NullableAttribute({1, 1, 1})"), + ("System.Collections.Generic.Dictionary?", "System.Runtime.CompilerServices.NullableAttribute({2, 2, 2})"), + ("System.Collections.Generic.Dictionary", "System.Runtime.CompilerServices.NullableAttribute({1, 4, 5})"), + ("System.Collections.Generic.Dictionary", "System.Runtime.CompilerServices.NullableAttribute({0, 1, 2})"), + ("System.Collections.Generic.Dictionary!", "System.Runtime.CompilerServices.NullableAttribute({1, 2, 0})"), + ("System.Collections.Generic.Dictionary?", "System.Runtime.CompilerServices.NullableAttribute({2, 0, 1})"), + ("System.String", "System.Runtime.CompilerServices.NullableAttribute({1, 1})"), + ("System.String", "System.Runtime.CompilerServices.NullableAttribute({})"), + ("System.Collections.Generic.Dictionary", "System.Runtime.CompilerServices.NullableAttribute({1, 1, 1, 1})"), + ("System.Collections.Generic.Dictionary", "System.Runtime.CompilerServices.NullableAttribute({1, 1})"), + ("System.Collections.Generic.Dictionary", "System.Runtime.CompilerServices.NullableAttribute({})"), + }; + + Assert.Equal(34, fieldsBaseline.Length); + AnnotationsInMetadataFieldSymbolValidator(b.ContainingModule, fieldsBaseline); + + (bool? constraintIsNullable, string attribute)[] typeParametersBaseline = new[] + { + ((bool?)null, "System.Runtime.CompilerServices.NullableAttribute(0)"), + (false, "System.Runtime.CompilerServices.NullableAttribute(1)"), + (true, "System.Runtime.CompilerServices.NullableAttribute(2)"), + (null, "System.Runtime.CompilerServices.NullableAttribute(3)"), + (null, "System.Runtime.CompilerServices.NullableAttribute(4)"), + (null, "System.Runtime.CompilerServices.NullableAttribute(5)"), + (null, "System.Runtime.CompilerServices.NullableAttribute({0})"), + (null, "System.Runtime.CompilerServices.NullableAttribute({1})"), + (null, "System.Runtime.CompilerServices.NullableAttribute({2})"), + (null, "System.Runtime.CompilerServices.NullableAttribute({1, 1})"), + (null, "System.Runtime.CompilerServices.NullableAttribute({})"), + (null, "System.Runtime.CompilerServices.NullableAttribute(null)"), + }; + + Assert.Equal(12, typeParametersBaseline.Length); + + for (int i = 0; i < typeParametersBaseline.Length; i++) + { + var t = b.TypeParameters[i]; + Assert.Equal(typeParametersBaseline[i].constraintIsNullable, t.ReferenceTypeConstraintIsNullable); + Assert.Equal(typeParametersBaseline[i].attribute, t.GetAttributes().Single().ToString()); + } + } + [Fact, WorkItem(30561, "https://github.com/dotnet/roslyn/issues/30561")] public void SetNullableStateInFinally_01() { From 98df03c6eb9896862c8ba45ab2550e196a4d48c0 Mon Sep 17 00:00:00 2001 From: AlekseyTs Date: Mon, 19 Nov 2018 13:48:45 -0800 Subject: [PATCH 4/5] Follow-up on merge from master --- .../CSharp/Portable/xlf/CSharpResources.cs.xlf | 10 ---------- .../CSharp/Portable/xlf/CSharpResources.de.xlf | 10 ---------- .../CSharp/Portable/xlf/CSharpResources.es.xlf | 10 ---------- .../CSharp/Portable/xlf/CSharpResources.fr.xlf | 10 ---------- .../CSharp/Portable/xlf/CSharpResources.it.xlf | 10 ---------- .../CSharp/Portable/xlf/CSharpResources.ja.xlf | 10 ---------- .../CSharp/Portable/xlf/CSharpResources.ko.xlf | 10 ---------- .../CSharp/Portable/xlf/CSharpResources.pl.xlf | 10 ---------- .../CSharp/Portable/xlf/CSharpResources.pt-BR.xlf | 10 ---------- .../CSharp/Portable/xlf/CSharpResources.ru.xlf | 10 ---------- .../CSharp/Portable/xlf/CSharpResources.tr.xlf | 10 ---------- .../CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf | 10 ---------- .../CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf | 10 ---------- 13 files changed, 130 deletions(-) diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf index 220580c2c942e..4c37a7978d94f 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf @@ -52,11 +52,6 @@ 'else' cannot start a statement. - - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - - Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. @@ -317,11 +312,6 @@ unmanaged generic type constraints - - injected declaration - injected declaration - - <null> <null> diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf index bf76a55bc82dd..de5b43d9022c7 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf @@ -52,11 +52,6 @@ 'else' cannot start a statement. - - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - - Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. @@ -317,11 +312,6 @@ unmanaged generic type constraints - - injected declaration - injected declaration - - <null> <NULL> diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf index 5c7daa00f5e6d..13a9c7e156bcb 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf @@ -52,11 +52,6 @@ 'else' cannot start a statement. - - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - - Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. @@ -317,11 +312,6 @@ unmanaged generic type constraints - - injected declaration - injected declaration - - <null> <NULL> diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf index 7b76f282f9b4d..6e96040e0821a 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf @@ -52,11 +52,6 @@ 'else' cannot start a statement. - - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - - Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. @@ -317,11 +312,6 @@ unmanaged generic type constraints - - injected declaration - injected declaration - - <null> <Null> diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf index 3d2ccdc565e34..2362e575c803c 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf @@ -52,11 +52,6 @@ 'else' cannot start a statement. - - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - - Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. @@ -317,11 +312,6 @@ unmanaged generic type constraints - - injected declaration - injected declaration - - <null> <Null> diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf index 63560bb9a650d..decef136ffa3c 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf @@ -52,11 +52,6 @@ 'else' cannot start a statement. - - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - - Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. @@ -317,11 +312,6 @@ unmanaged generic type constraints - - injected declaration - injected declaration - - <null> <null> diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf index 886dce844012f..08f130cf5a17c 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf @@ -52,11 +52,6 @@ 'else' cannot start a statement. - - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - - Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. @@ -317,11 +312,6 @@ unmanaged generic type constraints - - injected declaration - injected declaration - - <null> <null> diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf index 43e49f167187d..5dc50ddb1d7e5 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf @@ -52,11 +52,6 @@ 'else' cannot start a statement. - - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - - Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. @@ -317,11 +312,6 @@ unmanaged generic type constraints - - injected declaration - injected declaration - - <null> <null> diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf index 330194b769c93..fa4be4bc58879 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf @@ -52,11 +52,6 @@ 'else' cannot start a statement. - - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - - Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. @@ -317,11 +312,6 @@ unmanaged generic type constraints - - injected declaration - injected declaration - - <null> <nulo> diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf index 9d74c7081d003..ed30aba195836 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf @@ -52,11 +52,6 @@ 'else' cannot start a statement. - - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - - Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. @@ -317,11 +312,6 @@ unmanaged generic type constraints - - injected declaration - injected declaration - - <null> <NULL> diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf index 062dd67a4fd17..2ee72e9d99478 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf @@ -52,11 +52,6 @@ 'else' cannot start a statement. - - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - - Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. @@ -317,11 +312,6 @@ unmanaged generic type constraints - - injected declaration - injected declaration - - <null> <null> diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf index 159c6ee31f67f..f04c17dc27022 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf @@ -52,11 +52,6 @@ 'else' cannot start a statement. - - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - - Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. @@ -317,11 +312,6 @@ unmanaged generic type constraints - - injected declaration - injected declaration - - <null> <null> diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf index 7ceb647bd594f..648449a366e36 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf @@ -52,11 +52,6 @@ 'else' cannot start a statement. - - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. - - Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed. @@ -317,11 +312,6 @@ unmanaged generic type constraints - - injected declaration - injected declaration - - <null> <null> From 6160520e0c2988097ca836c3cd1ae27a118599a3 Mon Sep 17 00:00:00 2001 From: AlekseyTs Date: Mon, 19 Nov 2018 14:12:59 -0800 Subject: [PATCH 5/5] PR feedback. Closes #29683 Closes #29662 --- docs/features/nullable-reference-types.md | 9 ++++++--- .../CSharp/Portable/Symbols/TypeSymbolWithAnnotations.cs | 4 ++-- .../EditAndContinue/EditAndContinueStateMachineTests.cs | 4 ++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/docs/features/nullable-reference-types.md b/docs/features/nullable-reference-types.md index 1eda63318d5ec..719165ead649b 100644 --- a/docs/features/nullable-reference-types.md +++ b/docs/features/nullable-reference-types.md @@ -8,7 +8,7 @@ In source, nullable reference types are annotated with `?`. string? OptString; // may be null Dictionary? OptDictionaryOptValues; // dictionary may be null, values may be null ``` -A warning is reported when annotating a reference type or unconstrained generic type with `?` outside a `#nullable` context. +A warning is reported when annotating a reference type with `?` outside a `#nullable` context. In metadata, nullable reference types are annotated with a `[Nullable]` attribute. ```c# @@ -28,7 +28,8 @@ namespace System.Runtime.CompilerServices } ``` -Each type reference is accompanied by a NullableAttribute with an array of bytes, where 0 is Oblivious, 1 is NotAnnotated and 2 is Annotated. +Each type reference is accompanied by a NullableAttribute with an array of bytes, where 0 is Oblivious, 1 is NotAnnotated and 2 is Annotated. +All value types are marked with flag 0 (oblivious). To optimize trivial cases the attribute can be omitted, or instead can be replaced with an attribute that takes a single byte value rather than an array. @@ -41,7 +42,7 @@ Trivial/optimized cases: NullableAttribute(1) should be placed on a type parameter definition that has a `class!` constraint. NullableAttribute(2) should be placed on a type parameter definition that has a `class?` constraint. -Other forms of NullableAttribute ar not emitted on type parameter definitions and are not specially recognized on them. +Other forms of NullableAttribute are not emitted on type parameter definitions and are not specially recognized on them. The `NullableAttribute` type declaration is synthesized by the compiler if it is not included in the compilation, but is needed to produce the output. @@ -58,6 +59,8 @@ string[] Oblivious1; // string~[]~ [Nullable(new[] { 1, 1 })] string[] NotNull2; // string![]! [Nullable(new[] { 0, 2 })] string[] ObliviousMaybeNull; // string?[]~ [Nullable(new[] { 1, 2 })] string[] NotNullMaybeNull; // string?[]! +int Int; // int +Nullable NullableInt1; // Nullable ``` ## Declaration warnings _Describe warnings reported for declarations in initial binding._ diff --git a/src/Compilers/CSharp/Portable/Symbols/TypeSymbolWithAnnotations.cs b/src/Compilers/CSharp/Portable/Symbols/TypeSymbolWithAnnotations.cs index 8ff9ef870b488..953018512b831 100644 --- a/src/Compilers/CSharp/Portable/Symbols/TypeSymbolWithAnnotations.cs +++ b/src/Compilers/CSharp/Portable/Symbols/TypeSymbolWithAnnotations.cs @@ -967,8 +967,8 @@ public bool ApplyNullableTransforms(byte defaultTransformFlag, ImmutableArray. { result = CreateNonLazyType(newTypeSymbol, NullableAnnotation.Unknown, result.CustomModifiers); } diff --git a/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/EditAndContinueStateMachineTests.cs b/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/EditAndContinueStateMachineTests.cs index dca2a02677b6d..638e656af99ef 100644 --- a/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/EditAndContinueStateMachineTests.cs +++ b/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/EditAndContinueStateMachineTests.cs @@ -4814,7 +4814,7 @@ public IEnumerable F() Diagnostic(ErrorCode.ERR_EncUpdateFailedMissingAttribute, "F").WithArguments("C.F()", "System.Runtime.CompilerServices.IteratorStateMachineAttribute").WithLocation(12, 29)); } - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/29662")] + [Fact] public void AddedIteratorStateMachineAttribute() { var source0 = MarkedSource(@" @@ -4999,7 +4999,7 @@ public async Task F() Diagnostic(ErrorCode.ERR_EncUpdateFailedMissingAttribute, "F").WithArguments("C.F()", "System.Runtime.CompilerServices.AsyncStateMachineAttribute").WithLocation(6, 28)); } - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/29662")] + [Fact] public void AddedAsyncStateMachineAttribute() { var source0 = MarkedSource(@"