未验证 提交 1c4909d2 编写于 作者: C Charles Stoner 提交者: GitHub

Require partial method signatures to match (#47576)

* Require partial method signatures to match

* Revert changes

* Fix tests

* Fix tests

* Avoid duplicate errors for tuples

* Fix tests

* Update numbering

* Add distinct error for nullability mismatch

* PR feedback

* Another test

* Fix test

* Add warning wave warning

* Update comments

* Remove stale comments

* PR feedback

* Fix test

* PR feedback

* Update comments in CopyTypeCustomModifiers()
......@@ -6305,6 +6305,12 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<data name="ERR_PartialMethodRefReturnDifference" xml:space="preserve">
<value>Partial method declarations must have matching ref return values.</value>
</data>
<data name="WRN_PartialMethodTypeDifference" xml:space="preserve">
<value>Partial method declarations '{0}' and '{1}' have differences in parameter or return types.</value>
</data>
<data name="WRN_PartialMethodTypeDifference_Title" xml:space="preserve">
<value>Partial method declarations have differences in parameter or return types.</value>
</data>
<data name="IDS_TopLevelStatements" xml:space="preserve">
<value>top-level statements</value>
</data>
......
......@@ -1834,6 +1834,7 @@ internal enum ErrorCode
ERR_StaticAnonymousFunctionCannotCaptureThis = 8821,
ERR_OverrideDefaultConstraintNotSatisfied = 8822,
ERR_DefaultConstraintOverrideOnly = 8823,
WRN_PartialMethodTypeDifference = 8824,
ERR_RuntimeDoesNotSupportCovariantReturnsOfClasses = 8830,
ERR_RuntimeDoesNotSupportCovariantPropertiesOfClasses = 8831,
......
......@@ -231,6 +231,7 @@ internal static int GetWarningLevel(ErrorCode code)
case ErrorCode.WRN_SyncAndAsyncEntryPoints:
case ErrorCode.WRN_ParameterIsStaticClass:
case ErrorCode.WRN_ReturnTypeIsStaticClass:
case ErrorCode.WRN_PartialMethodTypeDifference:
// Warning level 5 is exclusively for warnings introduced in the compiler
// shipped with dotnet 5 (C# 9) and that can be reported for pre-existing code.
return 5;
......
......@@ -247,6 +247,7 @@ public static bool IsWarning(ErrorCode code)
case ErrorCode.WRN_GivenExpressionAlwaysMatchesPattern:
case ErrorCode.WRN_IsPatternAlways:
case ErrorCode.WRN_NullabilityMismatchInReturnTypeOnPartial:
case ErrorCode.WRN_PartialMethodTypeDifference:
case ErrorCode.WRN_SwitchExpressionNotExhaustiveWithWhen:
case ErrorCode.WRN_SwitchExpressionNotExhaustiveForNullWithWhen:
case ErrorCode.WRN_PrecedenceInversion:
......
......@@ -6,7 +6,6 @@
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using Microsoft.CodeAnalysis.PooledObjects;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.Symbols
......@@ -127,6 +126,19 @@ internal class MemberSignatureComparer : IEqualityComparer<Symbol>
considerRefKindDifferences: true,
typeComparison: TypeCompareKind.AllIgnoreOptions);
/// <summary>
/// This instance is used to determine if a partial method implementation matches the definition,
/// including differences ignored by the runtime.
/// </summary>
public static readonly MemberSignatureComparer PartialMethodsStrictComparer = new MemberSignatureComparer(
considerName: true,
considerExplicitlyImplementedInterfaces: true,
considerReturnType: true,
considerTypeConstraints: false,
considerCallingConvention: false,
considerRefKindDifferences: true,
typeComparison: TypeCompareKind.ObliviousNullableModifierMatchesAny);
/// <summary>
/// This instance is used to check whether one member overrides another, according to the C# definition.
/// </summary>
......
......@@ -60,7 +60,8 @@ internal static class CustomModifierUtils
}
/// <param name="sourceType">Type that already has custom modifiers.</param>
/// <param name="destinationType">Same as <paramref name="sourceType"/>, but without custom modifiers. May differ in object/dynamic.</param>
/// <param name="destinationType">Same as <paramref name="sourceType"/>, but without custom modifiers.
/// May differ in object/dynamic, tuple element names, or other differences ignored by the runtime.</param>
/// <param name="containingAssembly">The assembly containing the signature referring to the destination type.</param>
/// <returns><paramref name="destinationType"/> with custom modifiers copied from <paramref name="sourceType"/>.</returns>
internal static TypeSymbol CopyTypeCustomModifiers(TypeSymbol sourceType, TypeSymbol destinationType, AssemblySymbol containingAssembly)
......@@ -69,10 +70,9 @@ internal static TypeSymbol CopyTypeCustomModifiers(TypeSymbol sourceType, TypeSy
const RefKind refKind = RefKind.None;
// NOTE: overrides can differ by object/dynamic. If they do, we'll need to tweak newType before
// we can use it in place of this.Type. We do so by computing the dynamic transform flags that
// code gen uses and then passing them to the dynamic type decoder that metadata reading uses.
// NOTE: ref is irrelevant here since we are just encoding/decoding the type out of the signature context
// NOTE: overrides can differ by object/dynamic, tuple element names, etc.
// If they do, we'll need to tweak destinationType before we can use it in place of sourceType.
// NOTE: refKind is irrelevant here since we are just encoding/decoding the type.
ImmutableArray<bool> flags = CSharpCompilation.DynamicTransformsEncoder.EncodeWithoutCustomModifierFlags(destinationType, refKind);
TypeSymbol resultType = DynamicTypeDecoder.TransformTypeWithoutCustomModifierFlags(sourceType, containingAssembly, refKind, flags);
......
......@@ -2653,10 +2653,6 @@ internal Binder GetBinder(CSharpSyntaxNode syntaxNode)
{
diagnostics.Add(ErrorCode.ERR_PartialMethodMustHaveLatent, method.Locations[0], method);
}
else if (!(method.OtherPartOfPartial is null) && MemberSignatureComparer.ConsideringTupleNamesCreatesDifference(method, method.OtherPartOfPartial))
{
diagnostics.Add(ErrorCode.ERR_PartialMethodInconsistentTupleNames, method.Locations[0], method, method.OtherPartOfPartial);
}
else if (method is { IsPartialDefinition: true, OtherPartOfPartial: null, HasExplicitAccessModifier: true })
{
diagnostics.Add(ErrorCode.ERR_PartialMethodWithAccessibilityModsMustHaveImplementation, method.Locations[0], method);
......
......@@ -1174,7 +1174,7 @@ private bool IsValidOverrideReturnType(Symbol overridingSymbol, TypeWithAnnotati
location,
new FormattedSymbol(overridingParameter, SymbolDisplayFormat.ShortFormat));
internal static void CheckValidNullableMethodOverride<TArg>(
internal static bool CheckValidNullableMethodOverride<TArg>(
CSharpCompilation compilation,
MethodSymbol baseMethod,
MethodSymbol overrideMethod,
......@@ -1186,13 +1186,16 @@ private bool IsValidOverrideReturnType(Symbol overridingSymbol, TypeWithAnnotati
{
if (!PerformValidNullableOverrideCheck(compilation, baseMethod, overrideMethod))
{
return;
return false;
}
bool hasErrors = false;
if ((baseMethod.FlowAnalysisAnnotations & FlowAnalysisAnnotations.DoesNotReturn) == FlowAnalysisAnnotations.DoesNotReturn &&
(overrideMethod.FlowAnalysisAnnotations & FlowAnalysisAnnotations.DoesNotReturn) != FlowAnalysisAnnotations.DoesNotReturn)
{
diagnostics.Add(ErrorCode.WRN_DoesNotReturnMismatch, overrideMethod.Locations[0], new FormattedSymbol(overrideMethod, SymbolDisplayFormat.MinimallyQualifiedFormat));
hasErrors = true;
}
var conversions = compilation.Conversions.WithNullability(true);
......@@ -1211,7 +1214,7 @@ private bool IsValidOverrideReturnType(Symbol overridingSymbol, TypeWithAnnotati
baseMethod.ReturnTypeWithAnnotations.Type))
{
reportMismatchInReturnType(diagnostics, baseMethod, overrideMethod, false, extraArgument);
return;
return true;
}
// check top-level nullability including flow analysis annotations
......@@ -1223,42 +1226,44 @@ private bool IsValidOverrideReturnType(Symbol overridingSymbol, TypeWithAnnotati
overrideMethod.ReturnTypeFlowAnalysisAnnotations))
{
reportMismatchInReturnType(diagnostics, baseMethod, overrideMethod, true, extraArgument);
return;
return true;
}
}
if (reportMismatchInParameterType == null)
{
return;
}
for (int i = 0; i < baseParameters.Length; i++)
if (reportMismatchInParameterType != null)
{
var baseParameter = baseParameters[i];
var baseParameterType = baseParameter.TypeWithAnnotations;
var overrideParameter = overrideParameters[i + overrideParameterOffset];
var overrideParameterType = getNotNullIfNotNullOutputType(overrideParameter.TypeWithAnnotations, overrideParameter.NotNullIfParameterNotNull);
// check nested nullability
if (!isValidNullableConversion(
conversions,
overrideParameter.RefKind,
baseParameterType.Type,
overrideParameterType.Type))
{
reportMismatchInParameterType(diagnostics, baseMethod, overrideMethod, overrideParameter, false, extraArgument);
}
// check top-level nullability including flow analysis annotations
else if (!NullableWalker.AreParameterAnnotationsCompatible(
overrideParameter.RefKind,
baseParameterType,
baseParameter.FlowAnalysisAnnotations,
overrideParameterType,
overrideParameter.FlowAnalysisAnnotations))
for (int i = 0; i < baseParameters.Length; i++)
{
reportMismatchInParameterType(diagnostics, baseMethod, overrideMethod, overrideParameter, true, extraArgument);
var baseParameter = baseParameters[i];
var baseParameterType = baseParameter.TypeWithAnnotations;
var overrideParameter = overrideParameters[i + overrideParameterOffset];
var overrideParameterType = getNotNullIfNotNullOutputType(overrideParameter.TypeWithAnnotations, overrideParameter.NotNullIfParameterNotNull);
// check nested nullability
if (!isValidNullableConversion(
conversions,
overrideParameter.RefKind,
baseParameterType.Type,
overrideParameterType.Type))
{
reportMismatchInParameterType(diagnostics, baseMethod, overrideMethod, overrideParameter, false, extraArgument);
hasErrors = true;
}
// check top-level nullability including flow analysis annotations
else if (!NullableWalker.AreParameterAnnotationsCompatible(
overrideParameter.RefKind,
baseParameterType,
baseParameter.FlowAnalysisAnnotations,
overrideParameterType,
overrideParameter.FlowAnalysisAnnotations))
{
reportMismatchInParameterType(diagnostics, baseMethod, overrideMethod, overrideParameter, true, extraArgument);
hasErrors = true;
}
}
}
return hasErrors;
TypeWithAnnotations getNotNullIfNotNullOutputType(TypeWithAnnotations outputType, ImmutableHashSet<string> notNullIfParameterNotNull)
{
if (!notNullIfParameterNotNull.IsEmpty)
......
......@@ -602,13 +602,16 @@ private static void PartialMethodChecks(SourceOrdinaryMethodSymbol definition, S
Debug.Assert(!ReferenceEquals(definition, implementation));
MethodSymbol constructedDefinition = definition.ConstructIfGeneric(implementation.TypeArgumentsWithAnnotations);
bool returnTypesEqual = constructedDefinition.ReturnTypeWithAnnotations.Equals(implementation.ReturnTypeWithAnnotations, TypeCompareKind.AllIgnoreOptions);
if (!returnTypesEqual
&& !SourceMemberContainerTypeSymbol.IsOrContainsErrorType(implementation.ReturnType)
&& !SourceMemberContainerTypeSymbol.IsOrContainsErrorType(definition.ReturnType))
bool hasTypeDifferences = !constructedDefinition.ReturnTypeWithAnnotations.Equals(implementation.ReturnTypeWithAnnotations, TypeCompareKind.AllIgnoreOptions);
if (hasTypeDifferences)
{
diagnostics.Add(ErrorCode.ERR_PartialMethodReturnTypeDifference, implementation.Locations[0]);
}
else if (MemberSignatureComparer.ConsideringTupleNamesCreatesDifference(definition, implementation))
{
hasTypeDifferences = true;
diagnostics.Add(ErrorCode.ERR_PartialMethodInconsistentTupleNames, implementation.Locations[0], definition, implementation);
}
if (definition.RefKind != implementation.RefKind)
{
......@@ -656,24 +659,32 @@ private static void PartialMethodChecks(SourceOrdinaryMethodSymbol definition, S
PartialMethodConstraintsChecks(definition, implementation, diagnostics);
SourceMemberContainerTypeSymbol.CheckValidNullableMethodOverride(
if (SourceMemberContainerTypeSymbol.CheckValidNullableMethodOverride(
implementation.DeclaringCompilation,
constructedDefinition,
implementation,
diagnostics,
(diagnostics, implementedMethod, implementingMethod, topLevel, returnTypesEqual) =>
static (diagnostics, implementedMethod, implementingMethod, topLevel, arg) =>
{
if (returnTypesEqual)
{
// report only if this is an unsafe *nullability* difference
diagnostics.Add(ErrorCode.WRN_NullabilityMismatchInReturnTypeOnPartial, implementingMethod.Locations[0]);
}
// report only if this is an unsafe *nullability* difference
diagnostics.Add(ErrorCode.WRN_NullabilityMismatchInReturnTypeOnPartial, implementingMethod.Locations[0]);
},
(diagnostics, implementedMethod, implementingMethod, implementingParameter, blameAttributes, arg) =>
static (diagnostics, implementedMethod, implementingMethod, implementingParameter, blameAttributes, arg) =>
{
diagnostics.Add(ErrorCode.WRN_NullabilityMismatchInParameterTypeOnPartial, implementingMethod.Locations[0], new FormattedSymbol(implementingParameter, SymbolDisplayFormat.ShortFormat));
},
extraArgument: returnTypesEqual);
extraArgument: (object)null))
{
hasTypeDifferences = true;
}
if (!hasTypeDifferences &&
!MemberSignatureComparer.PartialMethodsStrictComparer.Equals(definition, implementation))
{
diagnostics.Add(ErrorCode.WRN_PartialMethodTypeDifference, implementation.Locations[0],
new FormattedSymbol(definition, SymbolDisplayFormat.MinimallyQualifiedFormat),
new FormattedSymbol(implementation, SymbolDisplayFormat.MinimallyQualifiedFormat));
}
}
private static void PartialMethodConstraintsChecks(SourceOrdinaryMethodSymbol definition, SourceOrdinaryMethodSymbol implementation, DiagnosticBag diagnostics)
......
......@@ -912,6 +912,26 @@
<target state="new">discards</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial_Title">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_PartialMethodTypeDifference">
<source>Partial method declarations '{0}' and '{1}' have differences in parameter or return types.</source>
<target state="new">Partial method declarations '{0}' and '{1}' have differences in parameter or return types.</target>
<note />
</trans-unit>
<trans-unit id="WRN_PartialMethodTypeDifference_Title">
<source>Partial method declarations have differences in parameter or return types.</source>
<target state="new">Partial method declarations have differences in parameter or return types.</target>
<note />
</trans-unit>
<trans-unit id="WRN_RecordNamedDisallowed">
<source>Types and aliases should not be named 'record'.</source>
<target state="new">Types and aliases should not be named 'record'.</target>
......@@ -2454,16 +2474,6 @@
<target state="translated">Typ odkazu s možnou hodnotou null ve vráceném typu neodpovídá přepsanému členu.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial_Title">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInTypeOnExplicitImplementation">
<source>Nullability of reference types in type doesn't match implemented member '{0}'.</source>
<target state="translated">Typ odkazu s možnou hodnotou null v typu neodpovídá implementovanému členu {0}.</target>
......
......@@ -912,6 +912,26 @@
<target state="new">discards</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial_Title">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_PartialMethodTypeDifference">
<source>Partial method declarations '{0}' and '{1}' have differences in parameter or return types.</source>
<target state="new">Partial method declarations '{0}' and '{1}' have differences in parameter or return types.</target>
<note />
</trans-unit>
<trans-unit id="WRN_PartialMethodTypeDifference_Title">
<source>Partial method declarations have differences in parameter or return types.</source>
<target state="new">Partial method declarations have differences in parameter or return types.</target>
<note />
</trans-unit>
<trans-unit id="WRN_RecordNamedDisallowed">
<source>Types and aliases should not be named 'record'.</source>
<target state="new">Types and aliases should not be named 'record'.</target>
......@@ -2454,16 +2474,6 @@
<target state="translated">Die NULL-Zulässigkeit von Verweistypen im Rückgabetyp entspricht nicht dem außer Kraft gesetzten Member.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial_Title">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInTypeOnExplicitImplementation">
<source>Nullability of reference types in type doesn't match implemented member '{0}'.</source>
<target state="translated">Die NULL-Zulässigkeit von Verweistypen im Typ entspricht nicht dem implementierten Member "{0}".</target>
......
......@@ -912,6 +912,26 @@
<target state="new">discards</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial_Title">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_PartialMethodTypeDifference">
<source>Partial method declarations '{0}' and '{1}' have differences in parameter or return types.</source>
<target state="new">Partial method declarations '{0}' and '{1}' have differences in parameter or return types.</target>
<note />
</trans-unit>
<trans-unit id="WRN_PartialMethodTypeDifference_Title">
<source>Partial method declarations have differences in parameter or return types.</source>
<target state="new">Partial method declarations have differences in parameter or return types.</target>
<note />
</trans-unit>
<trans-unit id="WRN_RecordNamedDisallowed">
<source>Types and aliases should not be named 'record'.</source>
<target state="new">Types and aliases should not be named 'record'.</target>
......@@ -2454,16 +2474,6 @@
<target state="translated">La nulabilidad de los tipos de referencia en el tipo de valor devuelto no coincide con el miembro reemplazado</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial_Title">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInTypeOnExplicitImplementation">
<source>Nullability of reference types in type doesn't match implemented member '{0}'.</source>
<target state="translated">La nulabilidad de los tipos de referencia del tipo no coincide con el miembro implementado "{0}".</target>
......
......@@ -912,6 +912,26 @@
<target state="new">discards</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial_Title">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_PartialMethodTypeDifference">
<source>Partial method declarations '{0}' and '{1}' have differences in parameter or return types.</source>
<target state="new">Partial method declarations '{0}' and '{1}' have differences in parameter or return types.</target>
<note />
</trans-unit>
<trans-unit id="WRN_PartialMethodTypeDifference_Title">
<source>Partial method declarations have differences in parameter or return types.</source>
<target state="new">Partial method declarations have differences in parameter or return types.</target>
<note />
</trans-unit>
<trans-unit id="WRN_RecordNamedDisallowed">
<source>Types and aliases should not be named 'record'.</source>
<target state="new">Types and aliases should not be named 'record'.</target>
......@@ -2454,16 +2474,6 @@
<target state="translated">La nullabilité des types référence dans le type de retour ne correspond pas au membre substitué.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial_Title">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInTypeOnExplicitImplementation">
<source>Nullability of reference types in type doesn't match implemented member '{0}'.</source>
<target state="translated">La nullabilité des types référence dans le type ne correspond pas au membre implémenté '{0}'.</target>
......
......@@ -912,6 +912,26 @@
<target state="new">discards</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial_Title">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_PartialMethodTypeDifference">
<source>Partial method declarations '{0}' and '{1}' have differences in parameter or return types.</source>
<target state="new">Partial method declarations '{0}' and '{1}' have differences in parameter or return types.</target>
<note />
</trans-unit>
<trans-unit id="WRN_PartialMethodTypeDifference_Title">
<source>Partial method declarations have differences in parameter or return types.</source>
<target state="new">Partial method declarations have differences in parameter or return types.</target>
<note />
</trans-unit>
<trans-unit id="WRN_RecordNamedDisallowed">
<source>Types and aliases should not be named 'record'.</source>
<target state="new">Types and aliases should not be named 'record'.</target>
......@@ -2454,16 +2474,6 @@
<target state="translated">Il supporto dei valori Null dei tipi riferimento nel tipo restituito non corrisponde al membro di cui è stato eseguito l'override.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial_Title">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInTypeOnExplicitImplementation">
<source>Nullability of reference types in type doesn't match implemented member '{0}'.</source>
<target state="translated">Il supporto dei valori Null dei tipi riferimento nel tipo non corrisponde al membro implementato '{0}'.</target>
......
......@@ -912,6 +912,26 @@
<target state="new">discards</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial_Title">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_PartialMethodTypeDifference">
<source>Partial method declarations '{0}' and '{1}' have differences in parameter or return types.</source>
<target state="new">Partial method declarations '{0}' and '{1}' have differences in parameter or return types.</target>
<note />
</trans-unit>
<trans-unit id="WRN_PartialMethodTypeDifference_Title">
<source>Partial method declarations have differences in parameter or return types.</source>
<target state="new">Partial method declarations have differences in parameter or return types.</target>
<note />
</trans-unit>
<trans-unit id="WRN_RecordNamedDisallowed">
<source>Types and aliases should not be named 'record'.</source>
<target state="new">Types and aliases should not be named 'record'.</target>
......@@ -2454,16 +2474,6 @@
<target state="translated">戻り値の型における参照型の Null 許容性が、オーバーライドされるメンバーと一致しません。</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial_Title">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInTypeOnExplicitImplementation">
<source>Nullability of reference types in type doesn't match implemented member '{0}'.</source>
<target state="translated">型における参照型の Null 許容性が、実装されるメンバー '{0}' と一致しません。</target>
......
......@@ -912,6 +912,26 @@
<target state="new">discards</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial_Title">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_PartialMethodTypeDifference">
<source>Partial method declarations '{0}' and '{1}' have differences in parameter or return types.</source>
<target state="new">Partial method declarations '{0}' and '{1}' have differences in parameter or return types.</target>
<note />
</trans-unit>
<trans-unit id="WRN_PartialMethodTypeDifference_Title">
<source>Partial method declarations have differences in parameter or return types.</source>
<target state="new">Partial method declarations have differences in parameter or return types.</target>
<note />
</trans-unit>
<trans-unit id="WRN_RecordNamedDisallowed">
<source>Types and aliases should not be named 'record'.</source>
<target state="new">Types and aliases should not be named 'record'.</target>
......@@ -2454,16 +2474,6 @@
<target state="translated">반환 형식에 있는 참조 형식 Null 허용 여부가 재정의된 멤버와 일치하지 않습니다.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial_Title">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInTypeOnExplicitImplementation">
<source>Nullability of reference types in type doesn't match implemented member '{0}'.</source>
<target state="translated">형식에 있는 참조 형식 Null 허용 여부가 구현된 멤버 '{0}'과(와) 일치하지 않습니다.</target>
......
......@@ -912,6 +912,26 @@
<target state="new">discards</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial_Title">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_PartialMethodTypeDifference">
<source>Partial method declarations '{0}' and '{1}' have differences in parameter or return types.</source>
<target state="new">Partial method declarations '{0}' and '{1}' have differences in parameter or return types.</target>
<note />
</trans-unit>
<trans-unit id="WRN_PartialMethodTypeDifference_Title">
<source>Partial method declarations have differences in parameter or return types.</source>
<target state="new">Partial method declarations have differences in parameter or return types.</target>
<note />
</trans-unit>
<trans-unit id="WRN_RecordNamedDisallowed">
<source>Types and aliases should not be named 'record'.</source>
<target state="new">Types and aliases should not be named 'record'.</target>
......@@ -2454,16 +2474,6 @@
<target state="translated">Obsługa wartości null dla typów referencyjnych w typie zwracanym jest niezgodna z przesłoniętą składową.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial_Title">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInTypeOnExplicitImplementation">
<source>Nullability of reference types in type doesn't match implemented member '{0}'.</source>
<target state="translated">Obsługa wartości null dla typów referencyjnych w typie jest niezgodna z implementowaną składową „{0}”.</target>
......
......@@ -912,6 +912,26 @@
<target state="new">discards</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial_Title">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_PartialMethodTypeDifference">
<source>Partial method declarations '{0}' and '{1}' have differences in parameter or return types.</source>
<target state="new">Partial method declarations '{0}' and '{1}' have differences in parameter or return types.</target>
<note />
</trans-unit>
<trans-unit id="WRN_PartialMethodTypeDifference_Title">
<source>Partial method declarations have differences in parameter or return types.</source>
<target state="new">Partial method declarations have differences in parameter or return types.</target>
<note />
</trans-unit>
<trans-unit id="WRN_RecordNamedDisallowed">
<source>Types and aliases should not be named 'record'.</source>
<target state="new">Types and aliases should not be named 'record'.</target>
......@@ -2452,16 +2472,6 @@
<target state="translated">A anulabilidade de tipos de referência em tipo de retorno não corresponde ao membro substituído.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial_Title">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInTypeOnExplicitImplementation">
<source>Nullability of reference types in type doesn't match implemented member '{0}'.</source>
<target state="translated">A anulabilidade de tipos de referência em tipo não corresponde ao membro implementado '{0}'.</target>
......
......@@ -912,6 +912,26 @@
<target state="new">discards</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial_Title">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_PartialMethodTypeDifference">
<source>Partial method declarations '{0}' and '{1}' have differences in parameter or return types.</source>
<target state="new">Partial method declarations '{0}' and '{1}' have differences in parameter or return types.</target>
<note />
</trans-unit>
<trans-unit id="WRN_PartialMethodTypeDifference_Title">
<source>Partial method declarations have differences in parameter or return types.</source>
<target state="new">Partial method declarations have differences in parameter or return types.</target>
<note />
</trans-unit>
<trans-unit id="WRN_RecordNamedDisallowed">
<source>Types and aliases should not be named 'record'.</source>
<target state="new">Types and aliases should not be named 'record'.</target>
......@@ -2454,16 +2474,6 @@
<target state="translated">Допустимость значения NULL для ссылочных типов в возвращаемом типе не совпадает с переопределенным членом.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial_Title">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInTypeOnExplicitImplementation">
<source>Nullability of reference types in type doesn't match implemented member '{0}'.</source>
<target state="translated">Допустимость значения NULL для ссылочных типов в типе не совпадает с реализованным членом "{0}".</target>
......
......@@ -912,6 +912,26 @@
<target state="new">discards</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial_Title">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_PartialMethodTypeDifference">
<source>Partial method declarations '{0}' and '{1}' have differences in parameter or return types.</source>
<target state="new">Partial method declarations '{0}' and '{1}' have differences in parameter or return types.</target>
<note />
</trans-unit>
<trans-unit id="WRN_PartialMethodTypeDifference_Title">
<source>Partial method declarations have differences in parameter or return types.</source>
<target state="new">Partial method declarations have differences in parameter or return types.</target>
<note />
</trans-unit>
<trans-unit id="WRN_RecordNamedDisallowed">
<source>Types and aliases should not be named 'record'.</source>
<target state="new">Types and aliases should not be named 'record'.</target>
......@@ -2454,16 +2474,6 @@
<target state="translated">Dönüş türündeki başvuru türlerinin boş değer atanabilirliği, geçersiz kılınan üye ile eşleşmiyor.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial_Title">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInTypeOnExplicitImplementation">
<source>Nullability of reference types in type doesn't match implemented member '{0}'.</source>
<target state="translated">Türdeki başvuru türlerinin boş değer atanabilirliği, uygulanan '{0}' üyesi ile eşleşmiyor.</target>
......
......@@ -912,6 +912,26 @@
<target state="new">discards</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial_Title">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_PartialMethodTypeDifference">
<source>Partial method declarations '{0}' and '{1}' have differences in parameter or return types.</source>
<target state="new">Partial method declarations '{0}' and '{1}' have differences in parameter or return types.</target>
<note />
</trans-unit>
<trans-unit id="WRN_PartialMethodTypeDifference_Title">
<source>Partial method declarations have differences in parameter or return types.</source>
<target state="new">Partial method declarations have differences in parameter or return types.</target>
<note />
</trans-unit>
<trans-unit id="WRN_RecordNamedDisallowed">
<source>Types and aliases should not be named 'record'.</source>
<target state="new">Types and aliases should not be named 'record'.</target>
......@@ -2454,16 +2474,6 @@
<target state="translated">返回类型中引用类型的为 Null 性与重写成员不匹配。</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial_Title">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInTypeOnExplicitImplementation">
<source>Nullability of reference types in type doesn't match implemented member '{0}'.</source>
<target state="translated">类型中引用类型的为 Null 性与实现的成员“{0}”不匹配。</target>
......
......@@ -912,6 +912,26 @@
<target state="new">discards</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial_Title">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_PartialMethodTypeDifference">
<source>Partial method declarations '{0}' and '{1}' have differences in parameter or return types.</source>
<target state="new">Partial method declarations '{0}' and '{1}' have differences in parameter or return types.</target>
<note />
</trans-unit>
<trans-unit id="WRN_PartialMethodTypeDifference_Title">
<source>Partial method declarations have differences in parameter or return types.</source>
<target state="new">Partial method declarations have differences in parameter or return types.</target>
<note />
</trans-unit>
<trans-unit id="WRN_RecordNamedDisallowed">
<source>Types and aliases should not be named 'record'.</source>
<target state="new">Types and aliases should not be named 'record'.</target>
......@@ -2454,16 +2474,6 @@
<target state="translated">傳回型別中參考型別的可 Null 性與覆寫的成員不符合。</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInReturnTypeOnPartial_Title">
<source>Nullability of reference types in return type doesn't match partial method declaration.</source>
<target state="new">Nullability of reference types in return type doesn't match partial method declaration.</target>
<note />
</trans-unit>
<trans-unit id="WRN_NullabilityMismatchInTypeOnExplicitImplementation">
<source>Nullability of reference types in type doesn't match implemented member '{0}'.</source>
<target state="translated">型別中參考型別的可 Null 性與實作的成員 '{0}' 不符合。</target>
......
......@@ -1249,6 +1249,7 @@ static void Main()
}
[Fact]
[WorkItem(45519, "https://github.com/dotnet/roslyn/issues/45519")]
public void EmitAttribute_PartialMethods()
{
var source =
......@@ -1260,13 +1261,21 @@ public void EmitAttribute_PartialMethods()
static partial void F2(nuint x);
}";
var comp = CreateCompilation(source, options: TestOptions.ReleaseDll.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular9);
// Ideally should not emit any attributes. Compare with dynamic/object.
var expected =
@"Program
void F2(System.UIntPtr x)
[NativeInteger] System.UIntPtr x
";
AssertNativeIntegerAttributes(comp, expected);
comp = CreateCompilation(source, options: TestOptions.ReleaseDllWithWarningLevel5, parseOptions: TestOptions.Regular9);
comp.VerifyEmitDiagnostics(
// (4,25): warning CS8824: Partial method declarations 'void Program.F2(nuint x)' and 'void Program.F2(UIntPtr x)' have differences in parameter or return types.
// static partial void F2(System.UIntPtr x) { }
Diagnostic(ErrorCode.WRN_PartialMethodTypeDifference, "F2").WithArguments("void Program.F2(nuint x)", "void Program.F2(UIntPtr x)").WithLocation(4, 25),
// (5,25): warning CS8824: Partial method declarations 'void Program.F1(IntPtr x)' and 'void Program.F1(nint x)' have differences in parameter or return types.
// static partial void F1(nint x) { }
Diagnostic(ErrorCode.WRN_PartialMethodTypeDifference, "F1").WithArguments("void Program.F1(IntPtr x)", "void Program.F1(nint x)").WithLocation(5, 25));
}
// Shouldn't depend on [NullablePublicOnly].
......
......@@ -20509,12 +20509,12 @@ public partial class C
";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics(
// (4,18): error CS8142: Both partial method declarations, 'C.M1((int a, int b))' and 'C.M1((int notA, int notB))', must use the same tuple element names.
// partial void M1((int a, int b) x);
Diagnostic(ErrorCode.ERR_PartialMethodInconsistentTupleNames, "M1").WithArguments("C.M1((int a, int b))", "C.M1((int notA, int notB))").WithLocation(4, 18),
// (5,18): error CS8142: Both partial method declarations, 'C.M2((int a, int b))' and 'C.M2((int, int))', must use the same tuple element names.
// partial void M2((int a, int b) x);
Diagnostic(ErrorCode.ERR_PartialMethodInconsistentTupleNames, "M2").WithArguments("C.M2((int a, int b))", "C.M2((int, int))").WithLocation(5, 18)
// (10,18): error CS8142: Both partial method declarations, 'C.M1((int a, int b))' and 'C.M1((int notA, int notB))', must use the same tuple element names.
// partial void M1((int notA, int notB) y) { }
Diagnostic(ErrorCode.ERR_PartialMethodInconsistentTupleNames, "M1").WithArguments("C.M1((int a, int b))", "C.M1((int notA, int notB))").WithLocation(10, 18),
// (11,18): error CS8142: Both partial method declarations, 'C.M2((int a, int b))' and 'C.M2((int, int))', must use the same tuple element names.
// partial void M2((int, int) y) { }
Diagnostic(ErrorCode.ERR_PartialMethodInconsistentTupleNames, "M2").WithArguments("C.M2((int a, int b))", "C.M2((int, int))").WithLocation(11, 18)
);
}
......@@ -3304,6 +3304,7 @@ class C2 : IA, IB
}
[Fact]
[WorkItem(45519, "https://github.com/dotnet/roslyn/issues/45519")]
public void Partial_01()
{
var source =
......@@ -3316,6 +3317,15 @@ public void Partial_01()
}";
var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9);
comp.VerifyDiagnostics();
comp = CreateCompilation(source, options: TestOptions.ReleaseDllWithWarningLevel5, parseOptions: TestOptions.Regular9);
comp.VerifyDiagnostics(
// (4,25): warning CS8824: Partial method declarations 'void Program.F2(nuint x)' and 'void Program.F2(UIntPtr x)' have differences in parameter or return types.
// static partial void F2(System.UIntPtr x) { }
Diagnostic(ErrorCode.WRN_PartialMethodTypeDifference, "F2").WithArguments("void Program.F2(nuint x)", "void Program.F2(UIntPtr x)").WithLocation(4, 25),
// (5,25): warning CS8824: Partial method declarations 'void Program.F1(IntPtr x)' and 'void Program.F1(nint x)' have differences in parameter or return types.
// static partial void F1(nint x) { }
Diagnostic(ErrorCode.WRN_PartialMethodTypeDifference, "F1").WithArguments("void Program.F1(IntPtr x)", "void Program.F1(nint x)").WithLocation(5, 25));
}
[Fact]
......
......@@ -17694,7 +17694,6 @@ partial class C1
{ }
}";
var compilation = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue());
// https://github.com/dotnet/roslyn/issues/30145: What nullability is getting emitted?
compilation.VerifyDiagnostics(
// (16,18): warning CS8611: Nullability of reference types in type of parameter 'y' doesn't match partial method declaration.
// partial void M1<T>(T? x, T[]? y, System.Action<T?> z, System.Action<T?[]?>?[]? u) where T : class
......@@ -17705,7 +17704,6 @@ partial class C1
);
var c1 = compilation.GetTypeByMetadataName("C1");
var m1 = c1.GetMember<MethodSymbol>("M1");
var m1Impl = m1.PartialImplementationPart;
var m1Def = m1.ConstructIfGeneric(m1Impl.TypeParameters.SelectAsArray(t => TypeWithAnnotations.Create(t)));
......@@ -17718,6 +17716,11 @@ partial class C1
Assert.True(m1Impl.Parameters[3].TypeWithAnnotations.Equals(m1Def.Parameters[3].TypeWithAnnotations,
TypeCompareKind.AllIgnoreOptions & ~TypeCompareKind.AllNullableIgnoreOptions));
compilation = CreateCompilation("", references: new[] { compilation.EmitToImageReference() }, options: TestOptions.ReleaseDll.WithMetadataImportOptions(MetadataImportOptions.All));
c1 = compilation.GetTypeByMetadataName("C1");
m1 = c1.GetMember<MethodSymbol>("M1");
Assert.Equal("void C1.M1<T>(T! x, T?[]! y, System.Action<T!>! z, System.Action<T?[]?>?[]? u)", m1.ToTestDisplayString(includeNonNullable: true));
}
[Fact]
......@@ -348,6 +348,7 @@ public void WarningLevel_2()
case ErrorCode.WRN_SyncAndAsyncEntryPoints:
case ErrorCode.WRN_ParameterIsStaticClass:
case ErrorCode.WRN_ReturnTypeIsStaticClass:
case ErrorCode.WRN_PartialMethodTypeDifference:
// These are the warnings introduced with the warning "wave" shipped with dotnet 5 and C# 9.
Assert.Equal(5, ErrorFacts.GetWarningLevel(errorCode));
break;
......@@ -407,6 +408,7 @@ public void NullableWarnings()
ErrorCode.WRN_ParameterIsStaticClass,
ErrorCode.WRN_ReturnTypeIsStaticClass,
ErrorCode.WRN_RecordNamedDisallowed,
ErrorCode.WRN_PartialMethodTypeDifference,
};
Assert.Contains(error, nullableUnrelatedWarnings);
......
......@@ -378,8 +378,10 @@ public override string ToString()
sb.Append('"');
}
sb.Append(", isSuppressed: ");
sb.Append(_isSuppressed ? "true" : "false");
if (_isSuppressed)
{
sb.Append(", isSuppressed: true");
}
sb.Append(")");
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册