diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx index b613b98efd186..efe21cbb9028b 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.resx +++ b/src/Compilers/CSharp/Portable/CSharpResources.resx @@ -6947,4 +6947,16 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ required members + + '{0}': cannot remove 'required' from '{1}' when overriding + + + Required member '{0}' cannot be hidden by '{1}'. + + + Required member '{0}' cannot be less visible than the containing type '{1}'. + + + Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead. + diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs index e40da273d7c5e..66c91cf9768c0 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs @@ -2033,5 +2033,9 @@ internal enum ErrorCode // PROTOTYPE(req): Move above the comment and condense before merge ERR_RequiredNameDisallowed = 9500, + ERR_OverrideMustHaveRequired = 9501, + ERR_RequiredMembersCannotBeHidden = 9502, + ERR_RequiredMembersCannotBeLessVisibleThanContainingType = 9503, + ERR_ExplicitRequiredMembers = 9504, } } diff --git a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/SynthesizedStateMachineProperty.cs b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/SynthesizedStateMachineProperty.cs index de2abd9ed0871..8ca68abb3e257 100644 --- a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/SynthesizedStateMachineProperty.cs +++ b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/SynthesizedStateMachineProperty.cs @@ -151,6 +151,8 @@ public override bool IsExtern get { return false; } } + internal override bool IsRequired => false; + internal override ObsoleteAttributeData ObsoleteAttributeData { get { return null; } diff --git a/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.FieldSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.FieldSymbol.cs index 10010ac113676..da38096f344db 100644 --- a/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.FieldSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.FieldSymbol.cs @@ -150,6 +150,8 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r ImmutableArray.Create( new TypedConstant(manager.System_Diagnostics_DebuggerBrowsableState, TypedConstantKind.Enum, DebuggerBrowsableState.Never)))); } + + internal override bool IsRequired => false; } } } diff --git a/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.PropertySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.PropertySymbol.cs index d55c65c360a9f..5d5630d1af30d 100644 --- a/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.PropertySymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.PropertySymbol.cs @@ -129,6 +129,8 @@ public override bool IsAbstract get { return false; } } + internal override bool IsRequired => false; + internal sealed override ObsoleteAttributeData ObsoleteAttributeData { get { return null; } diff --git a/src/Compilers/CSharp/Portable/Symbols/ErrorPropertySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/ErrorPropertySymbol.cs index 09256e0b3b6f8..536658ed92722 100644 --- a/src/Compilers/CSharp/Portable/Symbols/ErrorPropertySymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/ErrorPropertySymbol.cs @@ -77,6 +77,8 @@ public ErrorPropertySymbol(Symbol containingSymbol, TypeSymbol type, string name public override bool IsExtern { get { return false; } } + internal override bool IsRequired => false; + internal sealed override ObsoleteAttributeData ObsoleteAttributeData { get { return null; } } public override ImmutableArray Parameters { get { return ImmutableArray.Empty; } } diff --git a/src/Compilers/CSharp/Portable/Symbols/FieldSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/FieldSymbol.cs index 52953a754b53c..3d5fdb7b3d910 100644 --- a/src/Compilers/CSharp/Portable/Symbols/FieldSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/FieldSymbol.cs @@ -325,6 +325,11 @@ internal virtual FieldSymbol AsMember(NamedTypeSymbol newOwner) return newOwner.IsDefinition ? this : new SubstitutedFieldSymbol(newOwner as SubstitutedNamedTypeSymbol, this); } + /// + /// Returns true if this field is required to be set in an object initializer on object creation. + /// + internal abstract bool IsRequired { get; } + #region Use-Site Diagnostics internal override UseSiteInfo GetUseSiteInfo() diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEFieldSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEFieldSymbol.cs index 6895447a75757..f5d35611fd6f4 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEFieldSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEFieldSymbol.cs @@ -587,5 +587,8 @@ internal override ObsoleteAttributeData ObsoleteAttributeData { get { return null; } } + + // PROTOTYPE(req): Implement + internal override bool IsRequired => false; } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEPropertySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEPropertySymbol.cs index 4ea1a910336f1..8e24f9904c191 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEPropertySymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEPropertySymbol.cs @@ -462,6 +462,15 @@ public override bool IsStatic } } + internal override bool IsRequired + { + get + { + // PROTOTYPE(req): Implement + return false; + } + } + public override ImmutableArray Parameters { get { return _parameters; } diff --git a/src/Compilers/CSharp/Portable/Symbols/PropertySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/PropertySymbol.cs index 72d99b8ffed28..04078ac60e638 100644 --- a/src/Compilers/CSharp/Portable/Symbols/PropertySymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/PropertySymbol.cs @@ -182,6 +182,11 @@ public bool IsWriteOnly } } + /// + /// Returns true if this property is required to be set in an object initializer on object creation. + /// + internal abstract bool IsRequired { get; } + /// /// True if the property itself is excluded from code coverage instrumentation. /// True for source properties marked with . diff --git a/src/Compilers/CSharp/Portable/Symbols/SignatureOnlyPropertySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/SignatureOnlyPropertySymbol.cs index fee6bf4bcadeb..0c2297b9ce522 100644 --- a/src/Compilers/CSharp/Portable/Symbols/SignatureOnlyPropertySymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/SignatureOnlyPropertySymbol.cs @@ -85,6 +85,8 @@ public SignatureOnlyPropertySymbol( public override bool IsExtern { get { throw ExceptionUtilities.Unreachable; } } + internal override bool IsRequired => throw ExceptionUtilities.Unreachable; + internal override ObsoleteAttributeData ObsoleteAttributeData { get { throw ExceptionUtilities.Unreachable; } } public override AssemblySymbol ContainingAssembly { get { throw ExceptionUtilities.Unreachable; } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/ModifierUtils.cs b/src/Compilers/CSharp/Portable/Symbols/Source/ModifierUtils.cs index ceb889a17f5fa..c1bef4222d7c8 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/ModifierUtils.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/ModifierUtils.cs @@ -422,6 +422,14 @@ internal static CSDiagnosticInfo CheckAccessibility(DeclarationModifiers modifie } } + if ((modifiers & DeclarationModifiers.Required) != 0 + && symbol.Kind is SymbolKind.Property or SymbolKind.Field + && symbol.DeclaredAccessibility < symbol.ContainingType.DeclaredAccessibility) + { + // Required member '{0}' cannot be less visible than the containing type '{1}'. + return new CSDiagnosticInfo(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, symbol, symbol.ContainingType); + } + return null; } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldSymbol.cs index 08ab93bd28469..27f03f3938c9f 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldSymbol.cs @@ -154,6 +154,8 @@ internal sealed override bool HasRuntimeSpecialName return this.Name == WellKnownMemberNames.EnumBackingFieldName; } } + + internal override bool IsRequired => (Modifiers & DeclarationModifiers.Required) != 0; } internal abstract class SourceFieldSymbolWithSyntaxReference : SourceFieldSymbol diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs index 57b687b710fae..7a9ccdb3fcf06 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs @@ -1619,6 +1619,7 @@ protected void AfterMembersChecks(BindingDiagnosticBag diagnostics) CheckSequentialOnPartialType(diagnostics); CheckForProtectedInStaticClass(diagnostics); CheckForUnmatchedOperators(diagnostics); + CheckForRequiredMembers(diagnostics); var location = Locations[0]; var compilation = DeclaringCompilation; @@ -2352,6 +2353,15 @@ private void CheckForEqualityAndGetHashCode(BindingDiagnosticBag diagnostics) } } + private void CheckForRequiredMembers(BindingDiagnosticBag diagnostics) + { + if (GetMembersUnordered().Any(SymbolExtensions.IsRequired)) + { + // Ensure that an error is reported if the required constructor isn't present. + _ = Binder.GetWellKnownTypeMember(DeclaringCompilation, WellKnownMember.System_Runtime_CompilerServices_RequiredMembersAttribute__ctor, diagnostics, Locations[0]); + } + } + private bool TypeOverridesObjectMethod(string name) { foreach (var method in this.GetMembers(name).OfType()) diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol_ImplementationChecks.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol_ImplementationChecks.cs index 0911c864ce008..60b8c61a80f20 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol_ImplementationChecks.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol_ImplementationChecks.cs @@ -712,6 +712,12 @@ private void CheckNewModifier(Symbol symbol, bool isNew, BindingDiagnosticBag di AddHidingAbstractDiagnostic(symbol, symbolLocation, hiddenMember, diagnostics, ref unused); + if (hiddenMember.IsRequired()) + { + // Required member '{0}' cannot be hidden by '{1}'. + diagnostics.Add(ErrorCode.ERR_RequiredMembersCannotBeHidden, symbolLocation, hiddenMember, symbol); + } + return; } } @@ -900,6 +906,11 @@ void checkSingleOverriddenMember(Symbol overridingMember, Symbol overriddenMembe // it is ok to override with no tuple names, for compatibility with C# 6, but otherwise names should match diagnostics.Add(ErrorCode.ERR_CantChangeTupleNamesOnOverride, overridingMemberLocation, overridingMember, overriddenMember); } + else if (overriddenMember is PropertySymbol { IsRequired: true } && overridingMember is PropertySymbol { IsRequired: false }) + { + // '{0}': cannot remove 'required' from '{1}' when overriding + diagnostics.Add(ErrorCode.ERR_OverrideMustHaveRequired, overridingMemberLocation, overridingMember, overriddenMember); + } else { // As in dev11, we don't compare obsoleteness to the immediately-overridden member, @@ -1409,6 +1420,12 @@ private static void CheckNonOverrideMember( diagnostics.Add(ErrorCode.WRN_NewOrOverrideExpected, hidingMemberLocation, hidingMember, hiddenMember); diagnosticAdded = true; } + else if (hiddenMember.IsRequired()) + { + // Required member '{0}' cannot be hidden by '{1}'. + diagnostics.Add(ErrorCode.ERR_RequiredMembersCannotBeHidden, hidingMemberLocation, hiddenMember, hidingMember); + diagnosticAdded = true; + } if (diagnosticAdded) { diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs index cacbf6cb60e00..f654a111736ce 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs @@ -1110,7 +1110,16 @@ internal sealed override void DecodeWellKnownAttribute(ref DecodeWellKnownAttrib diagnostics.Add(ErrorCode.ERR_CantUseRequiredAttribute, arguments.AttributeSyntaxOpt.Name.Location); } else if (ReportExplicitUseOfReservedAttributes(in arguments, - ReservedAttributes.DynamicAttribute | ReservedAttributes.IsReadOnlyAttribute | ReservedAttributes.IsUnmanagedAttribute | ReservedAttributes.IsByRefLikeAttribute | ReservedAttributes.TupleElementNamesAttribute | ReservedAttributes.NullableAttribute | ReservedAttributes.NullableContextAttribute | ReservedAttributes.NativeIntegerAttribute | ReservedAttributes.CaseSensitiveExtensionAttribute)) + ReservedAttributes.DynamicAttribute + | ReservedAttributes.IsReadOnlyAttribute + | ReservedAttributes.IsUnmanagedAttribute + | ReservedAttributes.IsByRefLikeAttribute + | ReservedAttributes.TupleElementNamesAttribute + | ReservedAttributes.NullableAttribute + | ReservedAttributes.NullableContextAttribute + | ReservedAttributes.NativeIntegerAttribute + | ReservedAttributes.CaseSensitiveExtensionAttribute + | ReservedAttributes.RequiredMemberAttribute)) { } else if (attribute.IsTargetAttribute(this, AttributeDescription.SecurityCriticalAttribute) @@ -1583,6 +1592,39 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r AddSynthesizedAttribute(ref attributes, this.DeclaringCompilation.TrySynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_CompilerGeneratedAttribute__ctor)); } + + var requiredMembers = ArrayBuilder.GetInstance(); + foreach (var member in GetMembers()) + { + switch (member) + { + case SourceFieldSymbol { IsRequired: true }: + case SourcePropertySymbol { IsRequired: true, IsOverride: false }: + case SourcePropertySymbol { IsRequired: true, IsOverride: true, OverriddenProperty.IsRequired: false }: + requiredMembers.Add(member); + break; + } + } + + if (requiredMembers.Any()) + { + var stringType = compilation.GetSpecialType(SpecialType.System_String); + // Because GetMembers() is already sorted in lexical order, we don't need to do + // any additional sorting here. + var nameConstants = requiredMembers.SelectAsArray( + static (member, stringType) => new TypedConstant(stringType, TypedConstantKind.Primitive, member.Name), + stringType); + var stringArrayType = ArrayTypeSymbol.CreateSZArray(stringType.ContainingAssembly, TypeWithAnnotations.Create(stringType)); + + AddSynthesizedAttribute( + ref attributes, + compilation.TrySynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_RequiredMembersAttribute__ctor, + ImmutableArray.Create(new TypedConstant(stringArrayType, nameConstants)))); + + // PROTOTYPE(req): Add obsolete marker to constructors if required members and Obsolete hasn't already been emitted + } + + requiredMembers.Free(); } #endregion diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbolBase.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbolBase.cs index 17df109569781..26379673a21e5 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbolBase.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbolBase.cs @@ -89,6 +89,7 @@ protected SourcePropertySymbolBase( { Debug.Assert(!isExpressionBodied || !isAutoProperty); Debug.Assert(!isExpressionBodied || !hasInitializer); + Debug.Assert((modifiers & DeclarationModifiers.Required) == 0 || this is SourcePropertySymbol); _syntaxRef = syntax.GetReference(); Location = location; @@ -518,6 +519,8 @@ public override bool IsVirtual get { return (_modifiers & DeclarationModifiers.Virtual) != 0; } } + internal sealed override bool IsRequired => (_modifiers & DeclarationModifiers.Required) != 0; + internal bool IsNew { get { return (_modifiers & DeclarationModifiers.New) != 0; } diff --git a/src/Compilers/CSharp/Portable/Symbols/Symbol.cs b/src/Compilers/CSharp/Portable/Symbols/Symbol.cs index 14d0714f477eb..6c07312f1a32f 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Symbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Symbol.cs @@ -1367,6 +1367,7 @@ internal enum ReservedAttributes NullablePublicOnlyAttribute = 1 << 8, NativeIntegerAttribute = 1 << 9, CaseSensitiveExtensionAttribute = 1 << 10, + RequiredMemberAttribute = 1 << 11, } internal bool ReportExplicitUseOfReservedAttributes(in DecodeWellKnownAttributeArguments arguments, ReservedAttributes reserved) @@ -1421,6 +1422,12 @@ internal bool ReportExplicitUseOfReservedAttributes(in DecodeWellKnownAttributeA // ExtensionAttribute should not be set explicitly. diagnostics.Add(ErrorCode.ERR_ExplicitExtension, arguments.AttributeSyntaxOpt.Location); } + else if ((reserved & ReservedAttributes.RequiredMemberAttribute) != 0 && + attribute.IsTargetAttribute(this, AttributeDescription.RequiredMembersAttribute)) + { + // Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead. + diagnostics.Add(ErrorCode.ERR_ExplicitRequiredMembers, arguments.AttributeSyntaxOpt.Location); + } else { return false; diff --git a/src/Compilers/CSharp/Portable/Symbols/SymbolExtensions.cs b/src/Compilers/CSharp/Portable/Symbols/SymbolExtensions.cs index 7a27991ad8521..e3229851e39d6 100644 --- a/src/Compilers/CSharp/Portable/Symbols/SymbolExtensions.cs +++ b/src/Compilers/CSharp/Portable/Symbols/SymbolExtensions.cs @@ -839,5 +839,12 @@ internal static bool HasAsyncMethodBuilderAttribute(this Symbol symbol, [NotNull builderArgument = null; return false; } + + internal static bool IsRequired(this Symbol symbol) + => symbol switch + { + FieldSymbol { IsRequired: true } or PropertySymbol { IsRequired: true } => true, + _ => false + }; } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedBackingFieldSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedBackingFieldSymbol.cs index 6001d8b361c51..156c5ea333769 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedBackingFieldSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedBackingFieldSymbol.cs @@ -151,5 +151,7 @@ private void CheckForFieldTargetedAttribute(BindingDiagnosticBag diagnostics) } } } + + internal override bool IsRequired => false; } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedFieldSymbolBase.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedFieldSymbolBase.cs index 73a6dacbcf7ce..23b8a7b28a61c 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedFieldSymbolBase.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedFieldSymbolBase.cs @@ -192,5 +192,7 @@ public override bool IsImplicitlyDeclared { get { return true; } } + + internal override bool IsRequired => false; } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Wrapped/WrappedFieldSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Wrapped/WrappedFieldSymbol.cs index d623fd5268c5e..6bed480fef024 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Wrapped/WrappedFieldSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Wrapped/WrappedFieldSymbol.cs @@ -204,5 +204,7 @@ public override bool IsStatic return _underlyingField.IsStatic; } } + + internal override bool IsRequired => _underlyingField.IsRequired; } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Wrapped/WrappedPropertySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Wrapped/WrappedPropertySymbol.cs index e0ee3f5cdbbb8..1d2064b7410e8 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Wrapped/WrappedPropertySymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Wrapped/WrappedPropertySymbol.cs @@ -161,6 +161,8 @@ public override bool IsExtern } } + internal override bool IsRequired => _underlyingProperty.IsRequired; + internal override ObsoleteAttributeData ObsoleteAttributeData { get diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf index b4d987d271105..3839b2d3e896c 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf @@ -432,6 +432,11 @@ Přístupové objekty {0} a {1} by měly být buď oba jenom pro inicializaci, nebo ani jeden. + + Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead. + Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead. + + The given expression cannot be used in a fixed statement Daný výraz nelze použít v příkazu fixed. @@ -977,6 +982,11 @@ Metoda {0} určuje omezení default pro parametr typu {1}, ale odpovídající parametr typu {2} přepsané nebo explicitně implementované metody {3} není omezený na typ odkazu nebo hodnoty. + + '{0}': cannot remove 'required' from '{1}' when overriding + '{0}': cannot remove 'required' from '{1}' when overriding + + Method '{0}' specifies a 'class' constraint for type parameter '{1}', but corresponding type parameter '{2}' of overridden or explicitly implemented method '{3}' is not a reference type. Metoda {0} určuje omezení class pro parametr typu {1}, ale odpovídající parametr typu {2} přepsané nebo explicitně implementované metody {3} není odkazový typ. @@ -1087,6 +1097,16 @@ Relační vzory se nedají použít pro hodnotu Není číslo s plovoucí desetinnou čárkou. + + Required member '{0}' cannot be hidden by '{1}'. + Required member '{0}' cannot be hidden by '{1}'. + + + + Required member '{0}' cannot be less visible than the containing type '{1}'. + Required member '{0}' cannot be less visible than the containing type '{1}'. + + Types and aliases cannot not be named 'required'. Types and aliases cannot not be named 'required'. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf index a26a53dcb2ec7..89783b8f2df85 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf @@ -432,6 +432,11 @@ "init-only" muss entweder für beide oder für keine der Zugriffsmethoden "{0}" und "{1}" festgelegt sein. + + Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead. + Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead. + + The given expression cannot be used in a fixed statement Der angegebene Ausdruck kann nicht in einer fixed-Anweisung verwendet werden. @@ -977,6 +982,11 @@ Die Methode "{0}" gibt eine default-Einschränkung für den Typparameter "{1}" an, aber der zugehörige Typparameter "{2}" der überschriebenen oder explizit implementierten Methode "{3}" ist auf einen Verweistyp oder einen Werttyp beschränkt. + + '{0}': cannot remove 'required' from '{1}' when overriding + '{0}': cannot remove 'required' from '{1}' when overriding + + Method '{0}' specifies a 'class' constraint for type parameter '{1}', but corresponding type parameter '{2}' of overridden or explicitly implemented method '{3}' is not a reference type. Die Methode "{0}" gibt eine class-Einschränkung für den Typparameter "{1}" an, aber der zugehörige Typparameter "{2}" der außer Kraft gesetzten oder explizit implementierten Methode "{3}" ist kein Verweistyp. @@ -1087,6 +1097,16 @@ Relationale Muster dürfen nicht für Gleitkomma-NaNs verwendet werden. + + Required member '{0}' cannot be hidden by '{1}'. + Required member '{0}' cannot be hidden by '{1}'. + + + + Required member '{0}' cannot be less visible than the containing type '{1}'. + Required member '{0}' cannot be less visible than the containing type '{1}'. + + Types and aliases cannot not be named 'required'. Types and aliases cannot not be named 'required'. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf index e88006466b84a..d2f3f7759ce34 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf @@ -432,6 +432,11 @@ Los descriptores de acceso "{0}" y "{1}" deben ser los dos solo de inicialización o ninguno de ellos + + Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead. + Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead. + + The given expression cannot be used in a fixed statement La expresión proporcionada no se puede utilizar en una instrucción "fixed" @@ -977,6 +982,11 @@ El método "{0}" especifica una restricción "default" para el parámetro de tipo "{1}", pero el parámetro de tipo "{2}" correspondiente del método "{3}" invalidado o implementado explícitamente se restringe a un tipo de referencia o a un tipo de valor. + + '{0}': cannot remove 'required' from '{1}' when overriding + '{0}': cannot remove 'required' from '{1}' when overriding + + Method '{0}' specifies a 'class' constraint for type parameter '{1}', but corresponding type parameter '{2}' of overridden or explicitly implemented method '{3}' is not a reference type. El método "{0}" especifica una restricción "class" para el parámetro de tipo "{1}", pero el parámetro de tipo correspondiente "{2}" de los métodos invalidados o implementados explícitamente "{3}" no es un tipo de referencia. @@ -1087,6 +1097,16 @@ No se pueden usar patrones relacionales para un valor NaN de punto flotante. + + Required member '{0}' cannot be hidden by '{1}'. + Required member '{0}' cannot be hidden by '{1}'. + + + + Required member '{0}' cannot be less visible than the containing type '{1}'. + Required member '{0}' cannot be less visible than the containing type '{1}'. + + Types and aliases cannot not be named 'required'. Types and aliases cannot not be named 'required'. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf index 0e30ae0ddea5d..3a1922409a624 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf @@ -432,6 +432,11 @@ Les accesseurs '{0}' et '{1}' doivent tous deux être initialiseurs uniquement ou ne pas l'être + + Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead. + Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead. + + The given expression cannot be used in a fixed statement Impossible d'utiliser l'expression donnée dans une instruction fixed @@ -977,6 +982,11 @@ La méthode '{0}' spécifie une contrainte 'default' pour le paramètre de type '{1}', mais le paramètre de type '{2}' correspondant de la méthode substituée ou explicitement implémentée '{3}' est limité à un type référence ou à un type valeur. + + '{0}': cannot remove 'required' from '{1}' when overriding + '{0}': cannot remove 'required' from '{1}' when overriding + + Method '{0}' specifies a 'class' constraint for type parameter '{1}', but corresponding type parameter '{2}' of overridden or explicitly implemented method '{3}' is not a reference type. La méthode '{0}' spécifie une contrainte 'class' pour le paramètre de type '{1}', mais le paramètre de type '{2}' correspondant de la méthode substituée ou explicitement implémentée '{3}' n'est pas un type référence. @@ -1087,6 +1097,16 @@ Les modèles relationnels ne peuvent pas être utilisés pour une valeur NaN à virgule flottante. + + Required member '{0}' cannot be hidden by '{1}'. + Required member '{0}' cannot be hidden by '{1}'. + + + + Required member '{0}' cannot be less visible than the containing type '{1}'. + Required member '{0}' cannot be less visible than the containing type '{1}'. + + Types and aliases cannot not be named 'required'. Types and aliases cannot not be named 'required'. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf index a7835e3141be5..876d0de8aa0c2 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf @@ -432,6 +432,11 @@ Il tipo di sola inizializzazione può essere specificato per entrambe le funzioni di accesso '{0}' e '{1}' o per nessuna di esse + + Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead. + Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead. + + The given expression cannot be used in a fixed statement Non è possibile usare l'espressione specificata in un'istruzione fixed @@ -977,6 +982,11 @@ Il metodo '{0}' specifica un vincolo 'default' per il parametro di tipo '{1}', ma il parametro di tipo corrispondente '{2}' del metodo '{3}' sottoposto a override o implementato in modo esplicito è vincolato a un tipo riferimento a un tipo valore. + + '{0}': cannot remove 'required' from '{1}' when overriding + '{0}': cannot remove 'required' from '{1}' when overriding + + Method '{0}' specifies a 'class' constraint for type parameter '{1}', but corresponding type parameter '{2}' of overridden or explicitly implemented method '{3}' is not a reference type. Il metodo '{0}' specifica un vincolo 'class' per il parametro di tipo '{1}', ma il parametro di tipo corrispondente '{2}' del metodo '{3}' sottoposto a override o implementato in modo esplicito non è un tipo riferimento. @@ -1087,6 +1097,16 @@ Non è possibile usare i criteri relazionali per un valore NaN a virgola mobile. + + Required member '{0}' cannot be hidden by '{1}'. + Required member '{0}' cannot be hidden by '{1}'. + + + + Required member '{0}' cannot be less visible than the containing type '{1}'. + Required member '{0}' cannot be less visible than the containing type '{1}'. + + Types and aliases cannot not be named 'required'. Types and aliases cannot not be named 'required'. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf index 78ebd039843a8..361d1431522a2 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf @@ -432,6 +432,11 @@ アクセサー '{0}' と '{1}' は、両方 init 専用か、両方そうでないかのいずれかでなければなりません + + Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead. + Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead. + + The given expression cannot be used in a fixed statement 指定された式を fixed ステートメントで使用することはできません @@ -977,6 +982,11 @@ メソッド '{0}' は、型パラメーター '{1}' に対して 'default' 制約を指定していますが、オーバーライドされた、または明示的に実装されたメソッド '{3}' の対応する型パラメーター '{2}' は、参照型または値の型に制約されています。 + + '{0}': cannot remove 'required' from '{1}' when overriding + '{0}': cannot remove 'required' from '{1}' when overriding + + Method '{0}' specifies a 'class' constraint for type parameter '{1}', but corresponding type parameter '{2}' of overridden or explicitly implemented method '{3}' is not a reference type. メソッド '{0}' は、型パラメーター '{1}' に対して 'class' 制約を指定していますが、オーバーライドされた、または明示的に実装されたメソッド '{3}' の対応する型パラメーター '{2}' は参照型ではありません。 @@ -1087,6 +1097,16 @@ リレーショナル パターンは、浮動小数点の NaN に使用することはできません。 + + Required member '{0}' cannot be hidden by '{1}'. + Required member '{0}' cannot be hidden by '{1}'. + + + + Required member '{0}' cannot be less visible than the containing type '{1}'. + Required member '{0}' cannot be less visible than the containing type '{1}'. + + Types and aliases cannot not be named 'required'. Types and aliases cannot not be named 'required'. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf index d5fc12e260ebe..54db9f4a9cb80 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf @@ -432,6 +432,11 @@ '{0}' 및 '{1}' 접근자는 둘 다 초기값 전용이거나 둘 다 초기값 전용이 아니어야 합니다. + + Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead. + Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead. + + The given expression cannot be used in a fixed statement fixed 문에서는 지정된 식을 사용할 수 없습니다. @@ -977,6 +982,11 @@ 메서드 '{0}'이(가) 형식 매개 변수 '{1}'의 'default' 제약 조건을 지정하지만 재정의되었거나 명시적으로 구현된 메서드 '{3}'의 해당 형식 매개 변수 '{2}'이(가) 참조 형식 또는 값 형식으로 제한됩니다. + + '{0}': cannot remove 'required' from '{1}' when overriding + '{0}': cannot remove 'required' from '{1}' when overriding + + Method '{0}' specifies a 'class' constraint for type parameter '{1}', but corresponding type parameter '{2}' of overridden or explicitly implemented method '{3}' is not a reference type. '{0}' 메서드는 형식 매개 변수 '{1}'의 'class' 제약 조건을 지정하지만 재정의되었거나 명시적으로 구현된 '{3}' 메서드의 해당 형식 매개 변수 '{2}'이(가) 참조 형식이 아닙니다. @@ -1087,6 +1097,16 @@ 부동 소수점 NaN에는 관계형 패턴을 사용할 수 없습니다. + + Required member '{0}' cannot be hidden by '{1}'. + Required member '{0}' cannot be hidden by '{1}'. + + + + Required member '{0}' cannot be less visible than the containing type '{1}'. + Required member '{0}' cannot be less visible than the containing type '{1}'. + + Types and aliases cannot not be named 'required'. Types and aliases cannot not be named 'required'. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf index 1dfe4133834b8..1df1eab7f5e08 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf @@ -432,6 +432,11 @@ Tylko do inicjowania powinny być obie metody dostępu „{0}” i „{1}” albo żadna z nich + + Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead. + Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead. + + The given expression cannot be used in a fixed statement Podanego wyrażenia nie można użyć w instrukcji fixed @@ -977,6 +982,11 @@ Metoda „{0}” określa ograniczenie „default” dla parametru typu „{1}”, lecz odpowiadający parametr typu „{2}” przesłoniętej lub jawnie zaimplementowanej metody „{3}” jest ograniczony do typu odwołania lub typu wartości. + + '{0}': cannot remove 'required' from '{1}' when overriding + '{0}': cannot remove 'required' from '{1}' when overriding + + Method '{0}' specifies a 'class' constraint for type parameter '{1}', but corresponding type parameter '{2}' of overridden or explicitly implemented method '{3}' is not a reference type. Metoda „{0}” określa ograniczenie „class” dla parametru typu „{1}”, lecz odpowiadający parametr typu „{2}” przesłoniętej lub jawnie zaimplementowanej metody „{3}” nie jest typem referencyjnym. @@ -1087,6 +1097,16 @@ Wzorców relacyjnych nie można używać na potrzeby zmiennoprzecinkowej wartości NaN. + + Required member '{0}' cannot be hidden by '{1}'. + Required member '{0}' cannot be hidden by '{1}'. + + + + Required member '{0}' cannot be less visible than the containing type '{1}'. + Required member '{0}' cannot be less visible than the containing type '{1}'. + + Types and aliases cannot not be named 'required'. Types and aliases cannot not be named 'required'. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf index 319272bc30954..2f1f82ade1a33 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf @@ -432,6 +432,11 @@ Os acessadores '{0}' e '{1}' devem ser somente de inicialização ou nenhum + + Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead. + Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead. + + The given expression cannot be used in a fixed statement A expressão determinada não pode ser usada em uma instrução fixed @@ -977,6 +982,11 @@ O método '{0}' especifica uma restrição 'default' para o parâmetro de tipo '{1}', mas o parâmetro de tipo correspondente '{2}' do método substituído ou implementado explicitamente '{3}' está restrito por um tipo de referência ou um tipo de valor. + + '{0}': cannot remove 'required' from '{1}' when overriding + '{0}': cannot remove 'required' from '{1}' when overriding + + Method '{0}' specifies a 'class' constraint for type parameter '{1}', but corresponding type parameter '{2}' of overridden or explicitly implemented method '{3}' is not a reference type. O método '{0}' especifica uma restrição de 'class' para o parâmetro de tipo '{1}', mas o parâmetro de tipo correspondente '{2}' do método substituído ou implementado explicitamente '{3}' não é um tipo de referência. @@ -1087,6 +1097,16 @@ Os padrões relacionais não podem ser usados para um NaN de ponto flutuante. + + Required member '{0}' cannot be hidden by '{1}'. + Required member '{0}' cannot be hidden by '{1}'. + + + + Required member '{0}' cannot be less visible than the containing type '{1}'. + Required member '{0}' cannot be less visible than the containing type '{1}'. + + Types and aliases cannot not be named 'required'. Types and aliases cannot not be named 'required'. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf index feec841b41ff3..3575f8940b137 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf @@ -432,6 +432,11 @@ Каждый из методов доступа "{0}" и "{1}" должен вызываться только во время инициализации либо ни один из этих методов доступа не должен вызываться таким образом. + + Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead. + Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead. + + The given expression cannot be used in a fixed statement Заданное выражение невозможно использовать в операторе fixed @@ -977,6 +982,11 @@ Метод "{0}" задает ограничение "default" для параметра типа "{1}", но соответствующий параметр типа "{2}" переопределенного или явно реализованного метода "{3}" ограничен и может представлять собой только тип ссылки или тип значения. + + '{0}': cannot remove 'required' from '{1}' when overriding + '{0}': cannot remove 'required' from '{1}' when overriding + + Method '{0}' specifies a 'class' constraint for type parameter '{1}', but corresponding type parameter '{2}' of overridden or explicitly implemented method '{3}' is not a reference type. Метод "{0}" задает ограничение class для параметра типа "{1}", но соответствующий параметр типа "{2}" переопределенного или явно реализованного метода "{3}" не является ссылочным типом. @@ -1087,6 +1097,16 @@ Реляционные шаблоны не могут использоваться для NaN с плавающей запятой. + + Required member '{0}' cannot be hidden by '{1}'. + Required member '{0}' cannot be hidden by '{1}'. + + + + Required member '{0}' cannot be less visible than the containing type '{1}'. + Required member '{0}' cannot be less visible than the containing type '{1}'. + + Types and aliases cannot not be named 'required'. Types and aliases cannot not be named 'required'. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf index 9fe8487a4efa5..688141c10c389 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf @@ -432,6 +432,11 @@ '{0}' ve '{1}' erişimcilerinin ikisi de yalnızca init olmalıdır ya da ikisi de olmamalıdır + + Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead. + Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead. + + The given expression cannot be used in a fixed statement Belirtilen ifade, fixed deyiminde kullanılamıyor @@ -977,6 +982,11 @@ '{0}' metodu, '{1}' tür parametresi için bir 'default' kısıtlaması belirtiyor, ancak geçersiz kılınan veya açıkça uygulanan '{3}' metodunun karşılık gelen '{2}' tür parametresi bir başvuru türü veya değer türüyle kısıtlanmış. + + '{0}': cannot remove 'required' from '{1}' when overriding + '{0}': cannot remove 'required' from '{1}' when overriding + + Method '{0}' specifies a 'class' constraint for type parameter '{1}', but corresponding type parameter '{2}' of overridden or explicitly implemented method '{3}' is not a reference type. '{0}' yöntemi, '{1}' tür parametresi için bir 'class' kısıtlaması belirtiyor, ancak geçersiz kılınan veya açıkça uygulanan '{3}' yönteminin karşılık gelen '{2}' tür parametresi bir başvuru türü değil. @@ -1087,6 +1097,16 @@ İlişkisel desenler, kayan noktalı NaN için kullanılamaz. + + Required member '{0}' cannot be hidden by '{1}'. + Required member '{0}' cannot be hidden by '{1}'. + + + + Required member '{0}' cannot be less visible than the containing type '{1}'. + Required member '{0}' cannot be less visible than the containing type '{1}'. + + Types and aliases cannot not be named 'required'. Types and aliases cannot not be named 'required'. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf index 5a48fd424489f..3d083e9066b9b 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf @@ -432,6 +432,11 @@ 访问器 {0} 和 {1} 应同时为 init-only,或两者都不是 + + Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead. + Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead. + + The given expression cannot be used in a fixed statement 给定表达式不能用于 fixed 语句中 @@ -977,6 +982,11 @@ 方法“{0}”为类型参数“{1}”指定了 "default" 约束,但被替代的或显式实现的方法“{3}”的对应类型参数“{2}” 仅限于引用类型或值类型。 + + '{0}': cannot remove 'required' from '{1}' when overriding + '{0}': cannot remove 'required' from '{1}' when overriding + + Method '{0}' specifies a 'class' constraint for type parameter '{1}', but corresponding type parameter '{2}' of overridden or explicitly implemented method '{3}' is not a reference type. 方法 "{0}" 为类型参数 "{1}" 指定了 "class" 约束,但重写的或显式实现的方法 "{3}" 的对应类型参数 "{2}" 不是引用类型。 @@ -1087,6 +1097,16 @@ 关系模式可能不能用于浮点 NaN。 + + Required member '{0}' cannot be hidden by '{1}'. + Required member '{0}' cannot be hidden by '{1}'. + + + + Required member '{0}' cannot be less visible than the containing type '{1}'. + Required member '{0}' cannot be less visible than the containing type '{1}'. + + Types and aliases cannot not be named 'required'. Types and aliases cannot not be named 'required'. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf index c05c909f7bc44..0de23b5db9925 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf @@ -432,6 +432,11 @@ 存取子 '{0}' 與 '{1}' 不得同時是或不是僅供初始化 + + Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead. + Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead. + + The given expression cannot be used in a fixed statement 指定運算式無法用於 fixed 陳述式中 @@ -977,6 +982,11 @@ 方法 '{0}' 會為型別參數 '{1}' 指定 'default' 條件約束,但覆寫或明確實作方法 '{3}' 的對應型別參數 '{2}' 會限制為參考型別或實值型別。 + + '{0}': cannot remove 'required' from '{1}' when overriding + '{0}': cannot remove 'required' from '{1}' when overriding + + Method '{0}' specifies a 'class' constraint for type parameter '{1}', but corresponding type parameter '{2}' of overridden or explicitly implemented method '{3}' is not a reference type. 方法 '{0}' 會為型別參數 '{1}' 指定 'class' 條件約束,但覆寫或明確實作的方法 '{3}' 對應型別參數 '{2}' 不屬於參考型別。 @@ -1087,6 +1097,16 @@ 浮點 NaN 不可使用關聯性模式。 + + Required member '{0}' cannot be hidden by '{1}'. + Required member '{0}' cannot be hidden by '{1}'. + + + + Required member '{0}' cannot be less visible than the containing type '{1}'. + Required member '{0}' cannot be less visible than the containing type '{1}'. + + Types and aliases cannot not be named 'required'. Types and aliases cannot not be named 'required'. diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/MissingSpecialMember.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/MissingSpecialMember.cs index f1511be8f3a69..6876bb77c5da6 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/MissingSpecialMember.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/MissingSpecialMember.cs @@ -610,6 +610,7 @@ public void AllWellKnownTypes() case WellKnownType.System_Runtime_CompilerServices_NativeIntegerAttribute: case WellKnownType.System_Runtime_CompilerServices_IsExternalInit: case WellKnownType.System_Runtime_CompilerServices_DefaultInterpolatedStringHandler: + case WellKnownType.System_Runtime_CompilerServices_RequiredMembersAttribute: // Not yet in the platform. continue; case WellKnownType.Microsoft_CodeAnalysis_Runtime_Instrumentation: diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/RequiredMembersTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/RequiredMembersTests.cs index 6744ec9e860fd..f3687d968b369 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/RequiredMembersTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/RequiredMembersTests.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; +using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities; using Xunit; @@ -11,10 +13,42 @@ namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols; [CompilerTrait(CompilerFeature.RequiredMembers)] public class RequiredMembersTests : CSharpTestBase { + private const string RequiredMembersAttribute = @" +namespace System.Runtime.CompilerServices +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)] + public class RequiredMembersAttribute : Attribute + { + public RequiredMembersAttribute(params string[] members) + { + this.Members = members; + } + + public string[] Members { get; } + } +} +"; + + private CSharpCompilation CreateCompilationWithRequiredMembers(CSharpTestSource source, CSharpParseOptions? parseOptions = null, CSharpCompilationOptions? options = null) + => CreateCompilation(new[] { source, RequiredMembersAttribute }, options: options, parseOptions: parseOptions); + + private Action ValidateRequiredMembersInModule(string[] memberPaths) + { + return module => + { + foreach (var memberPath in memberPaths) + { + var member = module.GlobalNamespace.GetMember(memberPath); + Assert.True(member is PropertySymbol or FieldSymbol, $"Unexpected member symbol type {member.Kind}"); + Assert.True(member.IsRequired()); + } + }; + } + [Fact] public void InvalidModifierLocations() { - var comp = CreateCompilation(@" + var comp = CreateCompilationWithRequiredMembers(@" required class C1 { required void M(required int i) @@ -104,7 +138,7 @@ class C2 : I2 [Fact] public void InvalidModifierCombinations() { - var comp = CreateCompilation(@" + var comp = CreateCompilationWithRequiredMembers(@" unsafe struct C { required const int F1 = 1; @@ -136,48 +170,48 @@ unsafe struct C [Fact] public void LangVersion() { - var comp = CreateCompilation(@" + var comp = CreateCompilationWithRequiredMembers(@" class C { - required int Field; - required int Prop { get; set; } + internal required int Field; + internal required int Prop { get; set; } } ", parseOptions: TestOptions.Regular10); comp.VerifyDiagnostics( - // (4,18): error CS8652: The feature 'required members' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. - // required int Field; - Diagnostic(ErrorCode.ERR_FeatureInPreview, "Field").WithArguments("required members").WithLocation(4, 18), - // (4,18): warning CS0169: The field 'C.Field' is never used - // required int Field; - Diagnostic(ErrorCode.WRN_UnreferencedField, "Field").WithArguments("C.Field").WithLocation(4, 18), - // (5,18): error CS8652: The feature 'required members' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. - // required int Prop { get; set; } - Diagnostic(ErrorCode.ERR_FeatureInPreview, "Prop").WithArguments("required members").WithLocation(5, 18) + // (4,27): error CS8652: The feature 'required members' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // internal required int Field; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "Field").WithArguments("required members").WithLocation(4, 27), + // (4,27): warning CS0649: Field 'C.Field' is never assigned to, and will always have its default value 0 + // internal required int Field; + Diagnostic(ErrorCode.WRN_UnassignedInternalField, "Field").WithArguments("C.Field", "0").WithLocation(4, 27), + // (5,27): error CS8652: The feature 'required members' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // internal required int Prop { get; set; } + Diagnostic(ErrorCode.ERR_FeatureInPreview, "Prop").WithArguments("required members").WithLocation(5, 27) ); } [Fact] public void DuplicateKeyword() { - var comp = CreateCompilation(@" + var comp = CreateCompilationWithRequiredMembers(@" class C { - required required int Field; - required required int Prop { get; set; } + internal required required int Field; + internal required required int Prop { get; set; } } "); comp.VerifyDiagnostics( - // (4,14): error CS1004: Duplicate 'required' modifier - // required required int Field; - Diagnostic(ErrorCode.ERR_DuplicateModifier, "required").WithArguments("required").WithLocation(4, 14), - // (4,27): warning CS0169: The field 'C.Field' is never used - // required required int Field; - Diagnostic(ErrorCode.WRN_UnreferencedField, "Field").WithArguments("C.Field").WithLocation(4, 27), - // (5,14): error CS1004: Duplicate 'required' modifier - // required required int Prop { get; set; } - Diagnostic(ErrorCode.ERR_DuplicateModifier, "required").WithArguments("required").WithLocation(5, 14) + // (4,23): error CS1004: Duplicate 'required' modifier + // internal required required int Field; + Diagnostic(ErrorCode.ERR_DuplicateModifier, "required").WithArguments("required").WithLocation(4, 23), + // (4,36): warning CS0649: Field 'C.Field' is never assigned to, and will always have its default value 0 + // internal required required int Field; + Diagnostic(ErrorCode.WRN_UnassignedInternalField, "Field").WithArguments("C.Field", "0").WithLocation(4, 36), + // (5,23): error CS1004: Duplicate 'required' modifier + // internal required required int Prop { get; set; } + Diagnostic(ErrorCode.ERR_DuplicateModifier, "required").WithArguments("required").WithLocation(5, 23) ); } @@ -185,7 +219,7 @@ class C [CombinatorialData] public void InvalidNames(bool use10) { - var comp = CreateCompilation(@" + var comp = CreateCompilationWithRequiredMembers(@" namespace N1 { struct required {} @@ -281,4 +315,766 @@ class required {} } ); } + + [Fact] + public void MissingRequiredMembersAttribute() + { + var comp = CreateCompilation(@" +class C +{ + public required int I { get; } +}"); + + // (2,7): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.RequiredMembersAttribute..ctor' + // class C + var expected = Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "C").WithArguments("System.Runtime.CompilerServices.RequiredMembersAttribute", ".ctor").WithLocation(2, 7); + comp.VerifyDiagnostics(expected); + comp.VerifyEmitDiagnostics(expected); + } + + [Fact] + public void MissingRequiredMembersAttributeCtor() + { + var comp = CreateCompilation(@" +class C +{ + public required int I { get; } +} + +namespace System.Runtime.CompilerServices +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)] + public class RequiredMembersAttribute : Attribute + { + } +} +"); + + // (2,7): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.RequiredMembersAttribute..ctor' + // class C + var expected = Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "C").WithArguments("System.Runtime.CompilerServices.RequiredMembersAttribute", ".ctor").WithLocation(2, 7); + comp.VerifyDiagnostics(expected); + comp.VerifyEmitDiagnostics(expected); + } + + [Fact] + public void RequiredMembersAttributeEmitted() + { + var comp = CreateCompilationWithRequiredMembers(@" +class C +{ + public required int Prop { get; set; } + public required int Field; +} +"); + + var expectedRequiredMembers = new[] { "C.Prop", "C.Field" }; + + var verifier = CompileAndVerify(comp, sourceSymbolValidator: ValidateRequiredMembersInModule(expectedRequiredMembers)); + verifier.VerifyDiagnostics( + // (5,25): warning CS0649: Field 'C.Field' is never assigned to, and will always have its default value 0 + // public required int Field; + Diagnostic(ErrorCode.WRN_UnassignedInternalField, "Field").WithArguments("C.Field", "0").WithLocation(5, 25) + ); + + verifier.VerifyTypeIL("C", @" +.class private auto ansi beforefieldinit C + extends [netstandard]System.Object +{ + .custom instance void System.Runtime.CompilerServices.RequiredMembersAttribute::.ctor(string[]) = ( + 01 00 02 00 00 00 04 50 72 6f 70 05 46 69 65 6c + 64 00 00 + ) + // Fields + .field private int32 'k__BackingField' + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + .field public int32 Field + // Methods + .method public hidebysig specialname + instance int32 get_Prop () cil managed + { + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + // Method begins at RVA 0x2050 + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 C::'k__BackingField' + IL_0006: ret + } // end of method C::get_Prop + .method public hidebysig specialname + instance void set_Prop ( + int32 'value' + ) cil managed + { + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + // Method begins at RVA 0x2058 + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld int32 C::'k__BackingField' + IL_0007: ret + } // end of method C::set_Prop + .method public hidebysig specialname rtspecialname + instance void .ctor () cil managed + { + // Method begins at RVA 0x2061 + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [netstandard]System.Object::.ctor() + IL_0006: ret + } // end of method C::.ctor + // Properties + .property instance int32 Prop() + { + .get instance int32 C::get_Prop() + .set instance void C::set_Prop(int32) + } +} // end of class C +"); + } + + [Fact] + public void RequiredMembersAttributeEmitted_OverrideRequiredProperty_MissingRequiredOnOverride() + { + var comp = CreateCompilationWithRequiredMembers(@" +class Base +{ + public virtual required int Prop { get; set; } +} +class Dervied : Base +{ + public override int Prop { get; set; } +} +"); + + comp.VerifyDiagnostics( + // (8,25): error CS9501: 'Dervied.Prop': cannot remove 'required' from 'Base.Prop' when overriding + // public override int Prop { get; set; } + Diagnostic(ErrorCode.ERR_OverrideMustHaveRequired, "Prop").WithArguments("Dervied.Prop", "Base.Prop").WithLocation(8, 25) + ); + } + + [Fact] + public void RequiredMembersAttributeEmitted_OverrideRequiredProperty() + { + var comp = CreateCompilationWithRequiredMembers(@" +class Base +{ + public virtual required int Prop { get; set; } +} +class Derived : Base +{ + public override required int Prop { get; set; } +} +"); + + var expectedRequiredMembers = new[] { "Base.Prop", "Derived.Prop" }; + + var verifier = CompileAndVerify(comp, sourceSymbolValidator: ValidateRequiredMembersInModule(expectedRequiredMembers)); + verifier.VerifyDiagnostics(); + + verifier.VerifyTypeIL("Base", @" +.class private auto ansi beforefieldinit Base + extends [netstandard]System.Object +{ + .custom instance void System.Runtime.CompilerServices.RequiredMembersAttribute::.ctor(string[]) = ( + 01 00 01 00 00 00 04 50 72 6f 70 00 00 + ) + // Fields + .field private int32 'k__BackingField' + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + // Methods + .method public hidebysig specialname newslot virtual + instance int32 get_Prop () cil managed + { + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + // Method begins at RVA 0x2050 + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 Base::'k__BackingField' + IL_0006: ret + } // end of method Base::get_Prop + .method public hidebysig specialname newslot virtual + instance void set_Prop ( + int32 'value' + ) cil managed + { + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + // Method begins at RVA 0x2058 + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld int32 Base::'k__BackingField' + IL_0007: ret + } // end of method Base::set_Prop + .method public hidebysig specialname rtspecialname + instance void .ctor () cil managed + { + // Method begins at RVA 0x2061 + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [netstandard]System.Object::.ctor() + IL_0006: ret + } // end of method Base::.ctor + // Properties + .property instance int32 Prop() + { + .get instance int32 Base::get_Prop() + .set instance void Base::set_Prop(int32) + } +} // end of class Base +"); + + verifier.VerifyTypeIL("Derived", @" +.class private auto ansi beforefieldinit Derived + extends Base +{ + // Fields + .field private int32 'k__BackingField' + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + // Methods + .method public hidebysig specialname virtual + instance int32 get_Prop () cil managed + { + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + // Method begins at RVA 0x2069 + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 Derived::'k__BackingField' + IL_0006: ret + } // end of method Derived::get_Prop + .method public hidebysig specialname virtual + instance void set_Prop ( + int32 'value' + ) cil managed + { + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + // Method begins at RVA 0x2071 + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld int32 Derived::'k__BackingField' + IL_0007: ret + } // end of method Derived::set_Prop + .method public hidebysig specialname rtspecialname + instance void .ctor () cil managed + { + // Method begins at RVA 0x207a + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void Base::.ctor() + IL_0006: ret + } // end of method Derived::.ctor + // Properties + .property instance int32 Prop() + { + .get instance int32 Derived::get_Prop() + .set instance void Derived::set_Prop(int32) + } +} // end of class Derived +"); + } + + [Fact] + public void RequiredMembersAttributeEmitted_AddRequiredOnOverride() + { + var comp = CreateCompilationWithRequiredMembers(@" +class Base +{ + public virtual int Prop { get; set; } +} +class Derived : Base +{ + public override required int Prop { get; set; } +} +class DerivedDerived : Derived +{ + public override required int Prop { get; set; } +} +"); + + var expectedRequiredMembers = new[] { "Derived.Prop", "DerivedDerived.Prop" }; + + var verifier = CompileAndVerify(comp, sourceSymbolValidator: ValidateRequiredMembersInModule(expectedRequiredMembers)); + verifier.VerifyDiagnostics(); + + verifier.VerifyTypeIL("Base", @" +.class private auto ansi beforefieldinit Base + extends [netstandard]System.Object +{ + // Fields + .field private int32 'k__BackingField' + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + // Methods + .method public hidebysig specialname newslot virtual + instance int32 get_Prop () cil managed + { + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + // Method begins at RVA 0x2050 + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 Base::'k__BackingField' + IL_0006: ret + } // end of method Base::get_Prop + .method public hidebysig specialname newslot virtual + instance void set_Prop ( + int32 'value' + ) cil managed + { + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + // Method begins at RVA 0x2058 + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld int32 Base::'k__BackingField' + IL_0007: ret + } // end of method Base::set_Prop + .method public hidebysig specialname rtspecialname + instance void .ctor () cil managed + { + // Method begins at RVA 0x2061 + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [netstandard]System.Object::.ctor() + IL_0006: ret + } // end of method Base::.ctor + // Properties + .property instance int32 Prop() + { + .get instance int32 Base::get_Prop() + .set instance void Base::set_Prop(int32) + } +} // end of class Base +"); + + verifier.VerifyTypeIL("Derived", @" +.class private auto ansi beforefieldinit Derived + extends Base +{ + .custom instance void System.Runtime.CompilerServices.RequiredMembersAttribute::.ctor(string[]) = ( + 01 00 01 00 00 00 04 50 72 6f 70 00 00 + ) + // Fields + .field private int32 'k__BackingField' + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + // Methods + .method public hidebysig specialname virtual + instance int32 get_Prop () cil managed + { + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + // Method begins at RVA 0x2069 + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 Derived::'k__BackingField' + IL_0006: ret + } // end of method Derived::get_Prop + .method public hidebysig specialname virtual + instance void set_Prop ( + int32 'value' + ) cil managed + { + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + // Method begins at RVA 0x2071 + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld int32 Derived::'k__BackingField' + IL_0007: ret + } // end of method Derived::set_Prop + .method public hidebysig specialname rtspecialname + instance void .ctor () cil managed + { + // Method begins at RVA 0x207a + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void Base::.ctor() + IL_0006: ret + } // end of method Derived::.ctor + // Properties + .property instance int32 Prop() + { + .get instance int32 Derived::get_Prop() + .set instance void Derived::set_Prop(int32) + } +} // end of class Derived +"); + + verifier.VerifyTypeIL("DerivedDerived", @" +.class private auto ansi beforefieldinit DerivedDerived + extends Derived +{ + // Fields + .field private int32 'k__BackingField' + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + // Methods + .method public hidebysig specialname virtual + instance int32 get_Prop () cil managed + { + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + // Method begins at RVA 0x2082 + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 DerivedDerived::'k__BackingField' + IL_0006: ret + } // end of method DerivedDerived::get_Prop + .method public hidebysig specialname virtual + instance void set_Prop ( + int32 'value' + ) cil managed + { + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + // Method begins at RVA 0x208a + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld int32 DerivedDerived::'k__BackingField' + IL_0007: ret + } // end of method DerivedDerived::set_Prop + .method public hidebysig specialname rtspecialname + instance void .ctor () cil managed + { + // Method begins at RVA 0x2093 + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void Derived::.ctor() + IL_0006: ret + } // end of method DerivedDerived::.ctor + // Properties + .property instance int32 Prop() + { + .get instance int32 DerivedDerived::get_Prop() + .set instance void DerivedDerived::set_Prop(int32) + } +} // end of class DerivedDerived +"); + } + + [Fact] + public void HidingRequiredMembers() + { + var comp = CreateCompilationWithRequiredMembers(@" +#pragma warning disable CS0649 // Never assigned +class Base +{ + public required int Field; + public required int Prop { get; set; } +} +class Derived1 : Base +{ + public new int Field; // 1 + public new int Prop { get; set; } // 2 +} +class Derived2 : Base +{ + public new int Prop; // 3 + public new int Field { get; set; } // 4 +} +"); + + comp.VerifyDiagnostics( + // (10,20): error CS9502: Required member 'Base.Field' cannot be hidden by 'Derived1.Field'. + // public new int Field; // 1 + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeHidden, "Field").WithArguments("Base.Field", "Derived1.Field").WithLocation(10, 20), + // (11,20): error CS9502: Required member 'Base.Prop' cannot be hidden by 'Derived1.Prop'. + // public new int Prop { get; set; } // 2 + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeHidden, "Prop").WithArguments("Base.Prop", "Derived1.Prop").WithLocation(11, 20), + // (15,20): error CS9502: Required member 'Base.Prop' cannot be hidden by 'Derived2.Prop'. + // public new int Prop; // 3 + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeHidden, "Prop").WithArguments("Base.Prop", "Derived2.Prop").WithLocation(15, 20), + // (16,20): error CS9502: Required member 'Base.Field' cannot be hidden by 'Derived2.Field'. + // public new int Field { get; set; } // 4 + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeHidden, "Field").WithArguments("Base.Field", "Derived2.Field").WithLocation(16, 20) + ); + } + + [Fact] + public void RequiredMembersMustBeAsVisibleAsContainingType() + { + var comp = CreateCompilationWithRequiredMembers(@" +#pragma warning disable CS0649 // Never assigned +#pragma warning disable CS0169 // Never used +public class C1 +{ + public required int Prop1 { get; set; } + internal protected required int Prop2 { get; set; } + internal required int Prop3 { get; set; } + protected required int Prop4 { get; set; } + private protected required int Prop5 { get; set; } + private required int Prop6 { get; set; } + public required int Field1; + internal protected required int Field2; + internal required int Field3; + protected required int Field4; + private protected required int Field5; + private required int Field6; +} +internal class C2 +{ + public required int Prop1 { get; set; } + internal protected required int Prop2 { get; set; } + internal required int Prop3 { get; set; } + protected required int Prop4 { get; set; } + private protected required int Prop5 { get; set; } + private required int Prop6 { get; set; } + public required int Field1; + internal protected required int Field2; + internal required int Field3; + protected required int Field4; + private protected required int Field5; + private required int Field6; +} +internal class Outer +{ + protected internal class C3 + { + public required int Prop1 { get; set; } + internal required int Prop2 { get; set; } + internal protected required int Prop3 { get; set; } + protected required int Prop4 { get; set; } + private protected required int Prop5 { get; set; } + private required int Prop6 { get; set; } + public required int Field1; + internal required int Field2; + internal protected required int Field3; + protected required int Field4; + private protected required int Field5; + private required int Field6; + } + protected class C4 + { + public required int Prop1 { get; set; } + internal protected required int Prop2 { get; set; } + internal required int Prop3 { get; set; } + protected required int Prop4 { get; set; } + private protected required int Prop5 { get; set; } + private required int Prop6 { get; set; } + public required int Field1; + internal protected required int Field2; + internal required int Field3; + protected required int Field4; + private protected required int Field5; + private required int Field6; + } + private protected class C5 + { + public required int Prop1 { get; set; } + internal protected required int Prop2 { get; set; } + internal required int Prop3 { get; set; } + protected required int Prop4 { get; set; } + private protected required int Prop5 { get; set; } + private required int Prop6 { get; set; } + public required int Field1; + internal protected required int Field2; + internal required int Field3; + protected required int Field4; + private protected required int Field5; + private required int Field6; + } + private class C6 + { + public required int Prop1 { get; set; } + internal protected required int Prop2 { get; set; } + internal required int Prop3 { get; set; } + protected required int Prop4 { get; set; } + private protected required int Prop5 { get; set; } + private required int Prop6 { get; set; } + public required int Field1; + internal protected required int Field2; + internal required int Field3; + protected required int Field4; + private protected required int Field5; + private required int Field6; + } +} +"); + + comp.VerifyDiagnostics( + // (7,37): error CS9503: Required member 'C1.Prop2' cannot be less visible than the containing type 'C1'. + // internal protected required int Prop2 { get; set; } + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Prop2").WithArguments("C1.Prop2", "C1").WithLocation(7, 37), + // (8,27): error CS9503: Required member 'C1.Prop3' cannot be less visible than the containing type 'C1'. + // internal required int Prop3 { get; set; } + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Prop3").WithArguments("C1.Prop3", "C1").WithLocation(8, 27), + // (9,28): error CS9503: Required member 'C1.Prop4' cannot be less visible than the containing type 'C1'. + // protected required int Prop4 { get; set; } + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Prop4").WithArguments("C1.Prop4", "C1").WithLocation(9, 28), + // (10,36): error CS9503: Required member 'C1.Prop5' cannot be less visible than the containing type 'C1'. + // private protected required int Prop5 { get; set; } + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Prop5").WithArguments("C1.Prop5", "C1").WithLocation(10, 36), + // (11,26): error CS9503: Required member 'C1.Prop6' cannot be less visible than the containing type 'C1'. + // private required int Prop6 { get; set; } + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Prop6").WithArguments("C1.Prop6", "C1").WithLocation(11, 26), + // (13,37): error CS9503: Required member 'C1.Field2' cannot be less visible than the containing type 'C1'. + // internal protected required int Field2; + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Field2").WithArguments("C1.Field2", "C1").WithLocation(13, 37), + // (14,27): error CS9503: Required member 'C1.Field3' cannot be less visible than the containing type 'C1'. + // internal required int Field3; + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Field3").WithArguments("C1.Field3", "C1").WithLocation(14, 27), + // (15,28): error CS9503: Required member 'C1.Field4' cannot be less visible than the containing type 'C1'. + // protected required int Field4; + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Field4").WithArguments("C1.Field4", "C1").WithLocation(15, 28), + // (16,36): error CS9503: Required member 'C1.Field5' cannot be less visible than the containing type 'C1'. + // private protected required int Field5; + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Field5").WithArguments("C1.Field5", "C1").WithLocation(16, 36), + // (17,26): error CS9503: Required member 'C1.Field6' cannot be less visible than the containing type 'C1'. + // private required int Field6; + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Field6").WithArguments("C1.Field6", "C1").WithLocation(17, 26), + // (24,28): error CS9503: Required member 'C2.Prop4' cannot be less visible than the containing type 'C2'. + // protected required int Prop4 { get; set; } + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Prop4").WithArguments("C2.Prop4", "C2").WithLocation(24, 28), + // (25,36): error CS9503: Required member 'C2.Prop5' cannot be less visible than the containing type 'C2'. + // private protected required int Prop5 { get; set; } + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Prop5").WithArguments("C2.Prop5", "C2").WithLocation(25, 36), + // (26,26): error CS9503: Required member 'C2.Prop6' cannot be less visible than the containing type 'C2'. + // private required int Prop6 { get; set; } + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Prop6").WithArguments("C2.Prop6", "C2").WithLocation(26, 26), + // (30,28): error CS9503: Required member 'C2.Field4' cannot be less visible than the containing type 'C2'. + // protected required int Field4; + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Field4").WithArguments("C2.Field4", "C2").WithLocation(30, 28), + // (31,36): error CS9503: Required member 'C2.Field5' cannot be less visible than the containing type 'C2'. + // private protected required int Field5; + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Field5").WithArguments("C2.Field5", "C2").WithLocation(31, 36), + // (32,26): error CS9503: Required member 'C2.Field6' cannot be less visible than the containing type 'C2'. + // private required int Field6; + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Field6").WithArguments("C2.Field6", "C2").WithLocation(32, 26), + // (39,31): error CS9503: Required member 'Outer.C3.Prop2' cannot be less visible than the containing type 'Outer.C3'. + // internal required int Prop2 { get; set; } + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Prop2").WithArguments("Outer.C3.Prop2", "Outer.C3").WithLocation(39, 31), + // (41,32): error CS9503: Required member 'Outer.C3.Prop4' cannot be less visible than the containing type 'Outer.C3'. + // protected required int Prop4 { get; set; } + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Prop4").WithArguments("Outer.C3.Prop4", "Outer.C3").WithLocation(41, 32), + // (42,40): error CS9503: Required member 'Outer.C3.Prop5' cannot be less visible than the containing type 'Outer.C3'. + // private protected required int Prop5 { get; set; } + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Prop5").WithArguments("Outer.C3.Prop5", "Outer.C3").WithLocation(42, 40), + // (43,30): error CS9503: Required member 'Outer.C3.Prop6' cannot be less visible than the containing type 'Outer.C3'. + // private required int Prop6 { get; set; } + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Prop6").WithArguments("Outer.C3.Prop6", "Outer.C3").WithLocation(43, 30), + // (45,31): error CS9503: Required member 'Outer.C3.Field2' cannot be less visible than the containing type 'Outer.C3'. + // internal required int Field2; + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Field2").WithArguments("Outer.C3.Field2", "Outer.C3").WithLocation(45, 31), + // (47,32): error CS9503: Required member 'Outer.C3.Field4' cannot be less visible than the containing type 'Outer.C3'. + // protected required int Field4; + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Field4").WithArguments("Outer.C3.Field4", "Outer.C3").WithLocation(47, 32), + // (48,40): error CS9503: Required member 'Outer.C3.Field5' cannot be less visible than the containing type 'Outer.C3'. + // private protected required int Field5; + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Field5").WithArguments("Outer.C3.Field5", "Outer.C3").WithLocation(48, 40), + // (49,30): error CS9503: Required member 'Outer.C3.Field6' cannot be less visible than the containing type 'Outer.C3'. + // private required int Field6; + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Field6").WithArguments("Outer.C3.Field6", "Outer.C3").WithLocation(49, 30), + // (57,40): error CS9503: Required member 'Outer.C4.Prop5' cannot be less visible than the containing type 'Outer.C4'. + // private protected required int Prop5 { get; set; } + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Prop5").WithArguments("Outer.C4.Prop5", "Outer.C4").WithLocation(57, 40), + // (58,30): error CS9503: Required member 'Outer.C4.Prop6' cannot be less visible than the containing type 'Outer.C4'. + // private required int Prop6 { get; set; } + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Prop6").WithArguments("Outer.C4.Prop6", "Outer.C4").WithLocation(58, 30), + // (63,40): error CS9503: Required member 'Outer.C4.Field5' cannot be less visible than the containing type 'Outer.C4'. + // private protected required int Field5; + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Field5").WithArguments("Outer.C4.Field5", "Outer.C4").WithLocation(63, 40), + // (64,30): error CS9503: Required member 'Outer.C4.Field6' cannot be less visible than the containing type 'Outer.C4'. + // private required int Field6; + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Field6").WithArguments("Outer.C4.Field6", "Outer.C4").WithLocation(64, 30), + // (73,30): error CS9503: Required member 'Outer.C5.Prop6' cannot be less visible than the containing type 'Outer.C5'. + // private required int Prop6 { get; set; } + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Prop6").WithArguments("Outer.C5.Prop6", "Outer.C5").WithLocation(73, 30), + // (79,30): error CS9503: Required member 'Outer.C5.Field6' cannot be less visible than the containing type 'Outer.C5'. + // private required int Field6; + Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Field6").WithArguments("Outer.C5.Field6", "Outer.C5").WithLocation(79, 30) + ); + } + + [Fact] + public void RequiredMembersCannotBeExplicitInterfaceImplementations() + { + var comp = CreateCompilationWithRequiredMembers(@" +interface I +{ + int Prop { get; set; } +} +class C : I +{ + required int I.Prop { get; set; } +} +"); + + comp.VerifyDiagnostics( + // (8,20): error CS0106: The modifier 'required' is not valid for this item + // required int I.Prop { get; set; } + Diagnostic(ErrorCode.ERR_BadMemberFlag, "Prop").WithArguments("required").WithLocation(8, 20) + ); + } + + [Fact] + public void UsingRequiredMembersAttributeExplicitly() + { + var comp = CreateCompilationWithRequiredMembers(@" +using System.Runtime.CompilerServices; +[RequiredMembers(new[] { ""Prop"" })] +class C +{ + public int Prop { get; set; } +} +"); + + comp.VerifyDiagnostics( + // (3,2): error CS9504: Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead. + // [RequiredMembers(new[] { "Prop" })] + Diagnostic(ErrorCode.ERR_ExplicitRequiredMembers, @"RequiredMembers(new[] { ""Prop"" })").WithLocation(3, 2) + ); + + var prop = comp.SourceModule.GlobalNamespace.GetMember("C.Prop"); + Assert.False(prop.IsRequired); + } } diff --git a/src/Compilers/Core/Portable/MetadataReader/PEModule.cs b/src/Compilers/Core/Portable/MetadataReader/PEModule.cs index a4704092eb521..e7e6bd0a97824 100644 --- a/src/Compilers/Core/Portable/MetadataReader/PEModule.cs +++ b/src/Compilers/Core/Portable/MetadataReader/PEModule.cs @@ -1127,6 +1127,7 @@ internal ObsoleteAttributeData TryGetDeprecatedOrExperimentalOrObsoleteAttribute ObsoleteAttributeData obsoleteData = TryExtractObsoleteDataFromAttribute(info, decoder); switch (obsoleteData?.Message) { + // PROTOTYPE(req): Ignore required obsolete marker case ByRefLikeMarker when ignoreByRefLikeMarker: return null; } diff --git a/src/Compilers/Core/Portable/Symbols/Attributes/AttributeDescription.cs b/src/Compilers/Core/Portable/Symbols/Attributes/AttributeDescription.cs index 4dc73d5a53282..292669e9d8219 100644 --- a/src/Compilers/Core/Portable/Symbols/Attributes/AttributeDescription.cs +++ b/src/Compilers/Core/Portable/Symbols/Attributes/AttributeDescription.cs @@ -199,6 +199,7 @@ static AttributeDescription() private static readonly byte[][] s_signatures_HasThis_Void_Only = { s_signature_HasThis_Void }; private static readonly byte[][] s_signatures_HasThis_Void_String_Only = { s_signature_HasThis_Void_String }; + private static readonly byte[][] s_signatures_HasThis_Void_SzArray_String_Only = { s_signature_HasThis_Void_SzArray_String }; private static readonly byte[][] s_signatures_HasThis_Void_Type_Only = { s_signature_HasThis_Void_Type }; private static readonly byte[][] s_signatures_HasThis_Void_Boolean_Only = { s_signature_HasThis_Void_Boolean }; @@ -478,5 +479,6 @@ static AttributeDescription() internal static readonly AttributeDescription UnmanagedCallersOnlyAttribute = new AttributeDescription("System.Runtime.InteropServices", "UnmanagedCallersOnlyAttribute", s_signatures_HasThis_Void_Only); internal static readonly AttributeDescription InterpolatedStringHandlerAttribute = new AttributeDescription("System.Runtime.CompilerServices", "InterpolatedStringHandlerAttribute", s_signatures_HasThis_Void_Only); internal static readonly AttributeDescription InterpolatedStringHandlerArgumentAttribute = new AttributeDescription("System.Runtime.CompilerServices", "InterpolatedStringHandlerArgumentAttribute", s_signaturesOfInterpolatedStringArgumentAttribute); + internal static readonly AttributeDescription RequiredMembersAttribute = new AttributeDescription("System.Runtime.CompilerServices", "RequiredMembersAttribute", s_signatures_HasThis_Void_SzArray_String_Only); } } diff --git a/src/Compilers/Core/Portable/WellKnownMember.cs b/src/Compilers/Core/Portable/WellKnownMember.cs index b8ce5205655ec..b17789a712872 100644 --- a/src/Compilers/Core/Portable/WellKnownMember.cs +++ b/src/Compilers/Core/Portable/WellKnownMember.cs @@ -517,6 +517,9 @@ internal enum WellKnownMember System_Runtime_CompilerServices_DefaultInterpolatedStringHandler__ToStringAndClear, + System_Runtime_CompilerServices_RequiredMembersAttribute__ctor, + System_Runtime_CompilerServices_RequiredMembersAttribute__get_Members, + Count // Remember to update the AllWellKnownTypeMembers tests when making changes here diff --git a/src/Compilers/Core/Portable/WellKnownMembers.cs b/src/Compilers/Core/Portable/WellKnownMembers.cs index 00f6ae1bcf8a4..b2f9570027bf1 100644 --- a/src/Compilers/Core/Portable/WellKnownMembers.cs +++ b/src/Compilers/Core/Portable/WellKnownMembers.cs @@ -3535,6 +3535,21 @@ static WellKnownMembers() 0, // Method Signature (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_String, // Return Type + // System_Runtime_CompilerServices_RequiredMembersAttribute__ctor + (byte)MemberFlags.Constructor, // Flags + (byte)WellKnownType.ExtSentinel, (byte)(WellKnownType.System_Runtime_CompilerServices_RequiredMembersAttribute - WellKnownType.ExtSentinel), // DeclaringTypeId + 0, // Arity + 1, // Method Signature + (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Void, // Return Type + (byte)SignatureTypeCode.SZArray, (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_String, + + // System_Runtime_CompilerServices_RequiredMembersAttribute__get_Members + (byte)(MemberFlags.PropertyGet | MemberFlags.Static), // Flags + (byte)WellKnownType.ExtSentinel, (byte)(WellKnownType.System_Runtime_CompilerServices_RequiredMembersAttribute - WellKnownType.ExtSentinel), // DeclaringTypeId + 0, // Arity + 0, // Method Signature + (byte)SignatureTypeCode.SZArray, (byte)SignatureTypeCode.TypeHandle, (byte)WellKnownType.System_Collections_Generic_EqualityComparer_T,// Return Type + }; string[] allNames = new string[(int)WellKnownMember.Count] @@ -3979,6 +3994,8 @@ static WellKnownMembers() "Append", // System_Text_StringBuilder__AppendObject ".ctor", // System_Text_StringBuilder__ctor "ToStringAndClear", // System_Runtime_CompilerServices_DefaultInterpolatedStringHandler__ToStringAndClear + ".ctor", // System_Runtime_CompilerServices_RequiredMembersAttribute__ctor + "get_Members", // System_Runtime_CompilerServices_RequiredMembersAttribute__get_Members }; s_descriptors = MemberDescriptor.InitializeFromStream(new System.IO.MemoryStream(initializationBytes, writable: false), allNames); diff --git a/src/Compilers/Core/Portable/WellKnownTypes.cs b/src/Compilers/Core/Portable/WellKnownTypes.cs index 1ee9254677987..5962d69453a08 100644 --- a/src/Compilers/Core/Portable/WellKnownTypes.cs +++ b/src/Compilers/Core/Portable/WellKnownTypes.cs @@ -317,6 +317,8 @@ internal enum WellKnownType System_ArgumentNullException, + System_Runtime_CompilerServices_RequiredMembersAttribute, + NextAvailable, // Remember to update the AllWellKnownTypes tests when making changes here } @@ -625,6 +627,8 @@ internal static class WellKnownTypes "System.Text.StringBuilder", "System.Runtime.CompilerServices.DefaultInterpolatedStringHandler", "System.ArgumentNullException", + + "System.Runtime.CompilerServices.RequiredMembersAttribute" }; private static readonly Dictionary s_nameToTypeIdMap = new Dictionary((int)Count); diff --git a/src/Compilers/Test/Core/CompilationVerifier.cs b/src/Compilers/Test/Core/CompilationVerifier.cs index 1ed62d8b828c8..a23902e55a141 100644 --- a/src/Compilers/Test/Core/CompilationVerifier.cs +++ b/src/Compilers/Test/Core/CompilationVerifier.cs @@ -193,7 +193,7 @@ public void VerifyTypeIL(string typeName, string expected) Assert.True(found, "Could not find type named " + typeName); } } - AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, output.ToString(), escapeQuotes: false); + AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, output.ToString().Replace("\t", " "), escapeQuotes: false); } public void Emit(string expectedOutput, int? expectedReturnCode, string[] args, IEnumerable manifestResources, EmitOptions emitOptions, Verification peVerify, SignatureDescription[] expectedSignatures) diff --git a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/DisplayClassVariable.cs b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/DisplayClassVariable.cs index d04f935e73e1a..a175df54f20b1 100644 --- a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/DisplayClassVariable.cs +++ b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/DisplayClassVariable.cs @@ -159,6 +159,8 @@ public override bool IsVolatile get { return false; } } + public override bool IsRequired => throw ExceptionUtilities.Unreachable; + public override FlowAnalysisAnnotations FlowAnalysisAnnotations { get { return FlowAnalysisAnnotations.None; }