提交 adbce761 编写于 作者: A Alireza Habibi 提交者: Julien Couvreur

Relax ordering constraints for parameter modifiers (#23643)

Merging on behalf of @alrz. Thanks!
上级 e710720a
......@@ -1798,15 +1798,6 @@ internal class CSharpResources {
}
}
/// <summary>
/// Looks up a localized string similar to The parameter modifier &apos;{0}&apos; cannot be used after the modifier &apos;{1}&apos;.
/// </summary>
internal static string ERR_BadParameterModifiersOrder {
get {
return ResourceManager.GetString("ERR_BadParameterModifiersOrder", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Parameter {0} should not be declared with the &apos;{1}&apos; keyword.
/// </summary>
......
......@@ -5193,9 +5193,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<data name="ERR_InExtensionMustBeValueType" xml:space="preserve">
<value>The first parameter of an 'in' extension method '{0}' must be a value type.</value>
</data>
<data name="ERR_BadParameterModifiersOrder" xml:space="preserve">
<value>The parameter modifier '{0}' cannot be used after the modifier '{1}'</value>
</data>
<data name="ERR_FieldsInRoStruct" xml:space="preserve">
<value>Instance fields of readonly structs must be readonly.</value>
</data>
......
......@@ -1517,7 +1517,7 @@ internal enum ErrorCode
ERR_TypeReserved = 8336,
ERR_RefExtensionMustBeValueTypeOrConstrainedToOne = 8337,
ERR_InExtensionMustBeValueType = 8338,
ERR_BadParameterModifiersOrder = 8339,
// ERR_BadParameterModifiersOrder = 8339, // Modifier ordering is relaxed
ERR_FieldsInRoStruct = 8340,
ERR_AutoPropsInRoStruct = 8341,
......
......@@ -168,10 +168,6 @@ internal static void EnsureIsReadOnlyAttributeExists(ImmutableArray<ParameterSym
{
diagnostics.Add(ErrorCode.ERR_DupParamMod, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.RefKeyword));
}
else if (seenThis)
{
diagnostics.Add(ErrorCode.ERR_BadParameterModifiersOrder, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.RefKeyword), SyntaxFacts.GetText(SyntaxKind.ThisKeyword));
}
else if (seenParams)
{
diagnostics.Add(ErrorCode.ERR_ParamsCantBeWithModifier, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.RefKeyword));
......@@ -253,10 +249,6 @@ internal static void EnsureIsReadOnlyAttributeExists(ImmutableArray<ParameterSym
{
diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.InKeyword), SyntaxFacts.GetText(SyntaxKind.OutKeyword));
}
else if (seenThis)
{
diagnostics.Add(ErrorCode.ERR_BadParameterModifiersOrder, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.InKeyword), SyntaxFacts.GetText(SyntaxKind.ThisKeyword));
}
else if(seenRef)
{
diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.InKeyword), SyntaxFacts.GetText(SyntaxKind.RefKeyword));
......
......@@ -8500,11 +8500,6 @@ Pokud chcete odstranit toto varování, můžete místo toho použít /reference
<target state="translated">První parametr rozšiřující metody in {0} musí být typem hodnoty.</target>
<note />
</trans-unit>
<trans-unit id="ERR_BadParameterModifiersOrder">
<source>The parameter modifier '{0}' cannot be used after the modifier '{1}'</source>
<target state="translated">Modifikátor parametru {0} nejde použít za modifikátorem {1}.</target>
<note />
</trans-unit>
<trans-unit id="ERR_FieldsInRoStruct">
<source>Instance fields of readonly structs must be readonly.</source>
<target state="translated">Pole instancí struktur jen pro čtení musí být jen pro čtení.</target>
......
......@@ -8500,11 +8500,6 @@ Um die Warnung zu beheben, können Sie stattdessen /reference verwenden (Einbett
<target state="translated">Der erste Parameter einer in-Erweiterungsmethode "{0}" muss ein Werttyp sein.</target>
<note />
</trans-unit>
<trans-unit id="ERR_BadParameterModifiersOrder">
<source>The parameter modifier '{0}' cannot be used after the modifier '{1}'</source>
<target state="translated">Der Parametermodifizierer "{0}" kann nicht nach dem Modifizierer "{1}" verwendet werden. </target>
<note />
</trans-unit>
<trans-unit id="ERR_FieldsInRoStruct">
<source>Instance fields of readonly structs must be readonly.</source>
<target state="translated">Instanzfelder oder schreibgeschützte Strukturen müssen schreibgeschützt sein.</target>
......
......@@ -8500,11 +8500,6 @@ Para eliminar la advertencia puede usar /reference (establezca la propiedad Embe
<target state="translated">El primer parámetro de un método de extensión "in" "{0}" debe ser un tipo de valor.</target>
<note />
</trans-unit>
<trans-unit id="ERR_BadParameterModifiersOrder">
<source>The parameter modifier '{0}' cannot be used after the modifier '{1}'</source>
<target state="translated">El modificador de parámetro "{0}" no se puede usar después del modificador "{1}".</target>
<note />
</trans-unit>
<trans-unit id="ERR_FieldsInRoStruct">
<source>Instance fields of readonly structs must be readonly.</source>
<target state="translated">Los campos de instancia de las estructuras readonly deben ser readonly.</target>
......
......@@ -8500,11 +8500,6 @@ Pour supprimer l'avertissement, vous pouvez utiliser la commande /reference (dé
<target state="translated">Le premier paramètre d'une méthode d'extension 'in' '{0}' doit être un type valeur.</target>
<note />
</trans-unit>
<trans-unit id="ERR_BadParameterModifiersOrder">
<source>The parameter modifier '{0}' cannot be used after the modifier '{1}'</source>
<target state="translated">Impossible d'utiliser le modificateur de paramètre '{0}' après le modificateur '{1}'</target>
<note />
</trans-unit>
<trans-unit id="ERR_FieldsInRoStruct">
<source>Instance fields of readonly structs must be readonly.</source>
<target state="translated">Les champs d'instance de structs en lecture seule doivent être en lecture seule.</target>
......
......@@ -8500,11 +8500,6 @@ Per rimuovere l'avviso, è invece possibile usare /reference (impostare la propr
<target state="translated">Il primo parametro di un metodo di estensione 'in' '{0}' deve essere un tipo valore.</target>
<note />
</trans-unit>
<trans-unit id="ERR_BadParameterModifiersOrder">
<source>The parameter modifier '{0}' cannot be used after the modifier '{1}'</source>
<target state="translated">Non è possibile usare il modificatore di parametro '{0}' dopo il modificatore '{1}'</target>
<note />
</trans-unit>
<trans-unit id="ERR_FieldsInRoStruct">
<source>Instance fields of readonly structs must be readonly.</source>
<target state="translated">I campi di istanza di struct di sola lettura devono essere di sola lettura.</target>
......
......@@ -8500,11 +8500,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<target state="translated">in' 拡張メソッド '{0}' の最初のパラメーターは値型でなければなりません。</target>
<note />
</trans-unit>
<trans-unit id="ERR_BadParameterModifiersOrder">
<source>The parameter modifier '{0}' cannot be used after the modifier '{1}'</source>
<target state="translated">パラメーター修飾子 '{0}' は、修飾子 '{1}' の後に使用することはできません</target>
<note />
</trans-unit>
<trans-unit id="ERR_FieldsInRoStruct">
<source>Instance fields of readonly structs must be readonly.</source>
<target state="translated">読み取り専用の構造体のインスタンス フィールドは、読み取り専用である必要があります。</target>
......
......@@ -8500,11 +8500,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<target state="translated">in' 확장 메서드 '{0}'의 첫 번째 매개 변수는 값 형식이어야 합니다.</target>
<note />
</trans-unit>
<trans-unit id="ERR_BadParameterModifiersOrder">
<source>The parameter modifier '{0}' cannot be used after the modifier '{1}'</source>
<target state="translated">매개 변수 한정자 '{0}'을(를) '{1}' 한정자 뒤에 사용할 수 없습니다.</target>
<note />
</trans-unit>
<trans-unit id="ERR_FieldsInRoStruct">
<source>Instance fields of readonly structs must be readonly.</source>
<target state="translated">읽기 전용 구조체의 인스턴스 필드는 읽기 전용이어야 합니다.</target>
......
......@@ -8500,11 +8500,6 @@ Aby usunąć ostrzeżenie, możesz zamiast tego użyć opcji /reference (ustaw w
<target state="translated">Pierwszy parametr metody „{0}” rozszerzenia „in” musi być typem wartości.</target>
<note />
</trans-unit>
<trans-unit id="ERR_BadParameterModifiersOrder">
<source>The parameter modifier '{0}' cannot be used after the modifier '{1}'</source>
<target state="translated">Modyfikator parametru „{0}” nie może być używany po modyfikatorze „{1}”</target>
<note />
</trans-unit>
<trans-unit id="ERR_FieldsInRoStruct">
<source>Instance fields of readonly structs must be readonly.</source>
<target state="translated">Wystąpienia pól struktur tylko do odczytu muszą być tylko do odczytu.</target>
......
......@@ -8500,11 +8500,6 @@ Para incorporar informações de tipo de interoperabilidade para os dois assembl
<target state="translated">O primeiro parâmetro de um método de extensão "in" "{0}" deve ser um tipo de valor.</target>
<note />
</trans-unit>
<trans-unit id="ERR_BadParameterModifiersOrder">
<source>The parameter modifier '{0}' cannot be used after the modifier '{1}'</source>
<target state="translated">O modificador de parâmetro '{0}' não pode ser usado após o modificador '{1}'</target>
<note />
</trans-unit>
<trans-unit id="ERR_FieldsInRoStruct">
<source>Instance fields of readonly structs must be readonly.</source>
<target state="translated">Campos de instância de structs somente leitura devem ser somente leitura.</target>
......
......@@ -8500,11 +8500,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<target state="translated">Первый параметр метода расширения "in" "{0}" должен иметь тип значения.</target>
<note />
</trans-unit>
<trans-unit id="ERR_BadParameterModifiersOrder">
<source>The parameter modifier '{0}' cannot be used after the modifier '{1}'</source>
<target state="translated">Модификатор параметра "{0}" не может использоваться после модификатора "{1}"</target>
<note />
</trans-unit>
<trans-unit id="ERR_FieldsInRoStruct">
<source>Instance fields of readonly structs must be readonly.</source>
<target state="translated">Поля экземпляров в структурах только для чтения должны быть доступны только для чтения.</target>
......
......@@ -8500,11 +8500,6 @@ Uyarıyı kaldırmak için, /reference kullanabilirsiniz (Birlikte Çalışma T
<target state="translated">in' genişletme metodu '{0}' için ilk parametre, değer türünde olmalıdır.</target>
<note />
</trans-unit>
<trans-unit id="ERR_BadParameterModifiersOrder">
<source>The parameter modifier '{0}' cannot be used after the modifier '{1}'</source>
<target state="translated">{0}' parametre değiştiricisi, '{1}' değiştiricisinden sonra kullanılamaz</target>
<note />
</trans-unit>
<trans-unit id="ERR_FieldsInRoStruct">
<source>Instance fields of readonly structs must be readonly.</source>
<target state="translated">Salt okunur yapı birimlerinin örnek alanları salt okunur olmalıdır.</target>
......
......@@ -8500,11 +8500,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<target state="translated">"in" 扩展方法“{0}”的第一个参数必须是值类型。</target>
<note />
</trans-unit>
<trans-unit id="ERR_BadParameterModifiersOrder">
<source>The parameter modifier '{0}' cannot be used after the modifier '{1}'</source>
<target state="translated">参数修饰符“{0}”不能在“{1}”修饰符后使用</target>
<note />
</trans-unit>
<trans-unit id="ERR_FieldsInRoStruct">
<source>Instance fields of readonly structs must be readonly.</source>
<target state="translated">只读结构的实例字段必须为只读。</target>
......
......@@ -8500,11 +8500,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<target state="translated">in' 擴充方法 '{0}' 中的第一個參數,必須是實值型別。</target>
<note />
</trans-unit>
<trans-unit id="ERR_BadParameterModifiersOrder">
<source>The parameter modifier '{0}' cannot be used after the modifier '{1}'</source>
<target state="translated">參數修飾詞 '{0}' 不可用於修飾詞 '{1}' 之後</target>
<note />
</trans-unit>
<trans-unit id="ERR_FieldsInRoStruct">
<source>Instance fields of readonly structs must be readonly.</source>
<target state="translated">唯讀結構的執行個體欄位必須為唯讀。</target>
......
......@@ -1965,6 +1965,108 @@ public static class Ext
Assert.Equal(RefKind.In, symbol.RefKind);
}
[Fact]
public void ParameterSymbolsRetrievedThroughSemanticModel_RefExtensionMethods2()
{
var code = @"
public static class Ext
{
public static void Method(this ref int p) { }
}";
var comp = CreateCompilationWithMscorlibAndSystemCore(code).VerifyDiagnostics();
var tree = comp.SyntaxTrees.Single();
var parameter = tree.FindNodeOrTokenByKind(SyntaxKind.Parameter);
Assert.True(parameter.IsNode);
var model = comp.GetSemanticModel(tree);
var symbol = (ParameterSymbol)model.GetDeclaredSymbolForNode(parameter.AsNode());
Assert.Equal(RefKind.Ref, symbol.RefKind);
}
[Fact]
public void ParameterSymbolsRetrievedThroughSemanticModel_InExtensionMethods2()
{
var code = @"
public static class Ext
{
public static void Method(this in int p) { }
}";
var comp = CreateCompilationWithMscorlibAndSystemCore(code).VerifyDiagnostics();
var tree = comp.SyntaxTrees.Single();
var parameter = tree.FindNodeOrTokenByKind(SyntaxKind.Parameter);
Assert.True(parameter.IsNode);
var model = comp.GetSemanticModel(tree);
var symbol = (ParameterSymbol)model.GetDeclaredSymbolForNode(parameter.AsNode());
Assert.Equal(RefKind.In, symbol.RefKind);
}
[Fact]
public void BadContainingType_ThisWithRef()
{
var test = @"
using System;
public static class GenExtensions<X> where X : struct
{
//No type parameters
public static void Goo1(ref this int i) {}
public static void Goo1(ref this X x) {}
public static void Goo2(this ref int i) {}
public static void Goo2(this ref X x) {}
//Single type parameter
public static void Goo1<T>(ref this T t) where T : struct {}
public static void Goo1<T>(ref this X x) {}
public static void Goo2<T>(this ref T t) where T : struct {}
public static void Goo2<T>(this ref X x) {}
//Multiple type parameters
public static void Goo1<T,U,V>(ref this U u) where U : struct {}
public static void Goo1<T,U,V>(ref this X x) {}
public static void Goo2<T,U,V>(this ref U u) where U : struct {}
public static void Goo2<T,U,V>(this ref X x) {}
}
";
CreateCompilationWithMscorlibAndSystemCore(test).GetDeclarationDiagnostics().Verify(
// (3,21): error CS1106: Extension method must be defined in a non-generic static class
// public static class GenExtensions<X> where X : struct
Diagnostic(ErrorCode.ERR_BadExtensionAgg, "GenExtensions").WithLocation(3, 21),
// (3,21): error CS1106: Extension method must be defined in a non-generic static class
// public static class GenExtensions<X> where X : struct
Diagnostic(ErrorCode.ERR_BadExtensionAgg, "GenExtensions").WithLocation(3, 21),
// (3,21): error CS1106: Extension method must be defined in a non-generic static class
// public static class GenExtensions<X> where X : struct
Diagnostic(ErrorCode.ERR_BadExtensionAgg, "GenExtensions").WithLocation(3, 21),
// (3,21): error CS1106: Extension method must be defined in a non-generic static class
// public static class GenExtensions<X> where X : struct
Diagnostic(ErrorCode.ERR_BadExtensionAgg, "GenExtensions").WithLocation(3, 21),
// (3,21): error CS1106: Extension method must be defined in a non-generic static class
// public static class GenExtensions<X> where X : struct
Diagnostic(ErrorCode.ERR_BadExtensionAgg, "GenExtensions").WithLocation(3, 21),
// (3,21): error CS1106: Extension method must be defined in a non-generic static class
// public static class GenExtensions<X> where X : struct
Diagnostic(ErrorCode.ERR_BadExtensionAgg, "GenExtensions").WithLocation(3, 21),
// (3,21): error CS1106: Extension method must be defined in a non-generic static class
// public static class GenExtensions<X> where X : struct
Diagnostic(ErrorCode.ERR_BadExtensionAgg, "GenExtensions").WithLocation(3, 21),
// (3,21): error CS1106: Extension method must be defined in a non-generic static class
// public static class GenExtensions<X> where X : struct
Diagnostic(ErrorCode.ERR_BadExtensionAgg, "GenExtensions").WithLocation(3, 21),
// (3,21): error CS1106: Extension method must be defined in a non-generic static class
// public static class GenExtensions<X> where X : struct
Diagnostic(ErrorCode.ERR_BadExtensionAgg, "GenExtensions").WithLocation(3, 21),
// (3,21): error CS1106: Extension method must be defined in a non-generic static class
// public static class GenExtensions<X> where X : struct
Diagnostic(ErrorCode.ERR_BadExtensionAgg, "GenExtensions").WithLocation(3, 21),
// (3,21): error CS1106: Extension method must be defined in a non-generic static class
// public static class GenExtensions<X> where X : struct
Diagnostic(ErrorCode.ERR_BadExtensionAgg, "GenExtensions").WithLocation(3, 21),
// (3,21): error CS1106: Extension method must be defined in a non-generic static class
// public static class GenExtensions<X> where X : struct
Diagnostic(ErrorCode.ERR_BadExtensionAgg, "GenExtensions").WithLocation(3, 21));
}
[Fact]
public void UsingRefExtensionMethodsBeforeVersion7_2ProducesDiagnostics_RefSyntax_SameCompilation()
{
......
......@@ -3882,5 +3882,65 @@ public class BaseClass<TMember> : I1<TMember>
Assert.Empty(model.LookupSymbols(instance.Position, baseClass, "SetMember", includeReducedExtensionMethods: true));
Assert.Empty(model.LookupSymbols(instance.Position, baseClass, includeReducedExtensionMethods: true).Where(s => s.Name == "SetMembers"));
}
[Fact]
public void InExtensionMethods()
{
var source = @"
public static class C
{
public static void M1(this in int p) { }
public static void M2(in this int p) { }
}";
void Validator(ModuleSymbol module)
{
var type = module.GlobalNamespace.GetMember<NamedTypeSymbol>("C");
var method = type.GetMember<MethodSymbol>("M1");
Assert.True(method.IsExtensionMethod);
var parameter = method.Parameters[0];
Assert.Equal(parameter.Type.SpecialType, SpecialType.System_Int32);
Assert.Equal(RefKind.In, parameter.RefKind);
method = type.GetMember<MethodSymbol>("M2");
Assert.True(method.IsExtensionMethod);
parameter = method.Parameters[0];
Assert.Equal(parameter.Type.SpecialType, SpecialType.System_Int32);
Assert.Equal(RefKind.In, parameter.RefKind);
}
CompileAndVerify(source, validator: Validator, options: TestOptions.ReleaseDll);
}
[Fact]
public void RefExtensionMethods()
{
var source = @"
public static class C
{
public static void M1(this ref int p) { }
public static void M2(ref this int p) { }
}";
void Validator(ModuleSymbol module)
{
var type = module.GlobalNamespace.GetMember<NamedTypeSymbol>("C");
var method = type.GetMember<MethodSymbol>("M1");
Assert.True(method.IsExtensionMethod);
var parameter = method.Parameters[0];
Assert.Equal(parameter.Type.SpecialType, SpecialType.System_Int32);
Assert.Equal(RefKind.Ref, parameter.RefKind);
method = type.GetMember<MethodSymbol>("M2");
Assert.True(method.IsExtensionMethod);
parameter = method.Parameters[0];
Assert.Equal(parameter.Type.SpecialType, SpecialType.System_Int32);
Assert.Equal(RefKind.Ref, parameter.RefKind);
}
CompileAndVerify(source, validator: Validator, options: TestOptions.ReleaseDll);
}
}
}
......@@ -3084,79 +3084,32 @@ static void Main()
}
[Fact]
public void BadParameterModifiers_ThisWithRef()
public void BadRefOrInWithThisParameterModifiers()
{
var test = @"
using System;
public static class Extensions
{
//No type parameters
public static void Goo1(this ref int i) {}
//Single type parameter
public static void Goo1<T>(this ref T t) where T : struct {}
//Multiple type parameters
public static void Goo1<T,U,V>(this ref U u) where U : struct {}
}
public static class GenExtensions<X> where X : struct
{
//No type parameters
public static void Goo2(this ref int i) {}
public static void Goo2(this ref X x) {}
//Single type parameter
public static void Goo2<T>(this ref T t) where T : struct {}
public static void Goo2<T>(this ref X x) {}
//Multiple type parameters
public static void Goo2<T,U,V>(this ref U u) where U : struct {}
public static void Goo2<T,U,V>(this ref X x) {}
public static void M1(ref this ref int i) {}
public static void M2(ref this in int i) {}
public static void M3(in this ref int i) {}
public static void M4(in this in int i) {}
}
";
CreateCompilationWithMscorlibAndSystemCore(test).GetDeclarationDiagnostics().Verify(
// (10,41): error CS8328: The parameter modifier 'ref' cannot be used after the modifier 'this'
// public static void Goo1<T,U,V>(this ref U u) {}
Diagnostic(ErrorCode.ERR_BadParameterModifiersOrder, "ref").WithArguments("ref", "this").WithLocation(10, 41),
// (22,41): error CS8339: The parameter modifier 'ref' cannot be used after the modifier 'this'
// public static void Goo2<T,U,V>(this ref X x) {}
Diagnostic(ErrorCode.ERR_BadParameterModifiersOrder, "ref").WithArguments("ref", "this").WithLocation(22, 41),
// (12,21): error CS1106: Extension method must be defined in a non-generic static class
// public static class GenExtensions<X>
Diagnostic(ErrorCode.ERR_BadExtensionAgg, "GenExtensions").WithLocation(12, 21),
// (8,37): error CS8339: The parameter modifier 'ref' cannot be used after the modifier 'this'
// public static void Goo1<T>(this ref T t) {}
Diagnostic(ErrorCode.ERR_BadParameterModifiersOrder, "ref").WithArguments("ref", "this").WithLocation(8, 37),
// (16,34): error CS8339: The parameter modifier 'ref' cannot be used after the modifier 'this'
// public static void Goo2(this ref X x) {}
Diagnostic(ErrorCode.ERR_BadParameterModifiersOrder, "ref").WithArguments("ref", "this").WithLocation(16, 34),
// (12,21): error CS1106: Extension method must be defined in a non-generic static class
// public static class GenExtensions<X>
Diagnostic(ErrorCode.ERR_BadExtensionAgg, "GenExtensions").WithLocation(12, 21),
// (6,34): error CS8339: The parameter modifier 'ref' cannot be used after the modifier 'this'
// public static void Goo1(this ref int i) {}
Diagnostic(ErrorCode.ERR_BadParameterModifiersOrder, "ref").WithArguments("ref", "this").WithLocation(6, 34),
// (18,37): error CS8339: The parameter modifier 'ref' cannot be used after the modifier 'this'
// public static void Goo2<T>(this ref T t) {}
Diagnostic(ErrorCode.ERR_BadParameterModifiersOrder, "ref").WithArguments("ref", "this").WithLocation(18, 37),
// (12,21): error CS1106: Extension method must be defined in a non-generic static class
// public static class GenExtensions<X>
Diagnostic(ErrorCode.ERR_BadExtensionAgg, "GenExtensions").WithLocation(12, 21),
// (19,37): error CS8339: The parameter modifier 'ref' cannot be used after the modifier 'this'
// public static void Goo2<T>(this ref X x) {}
Diagnostic(ErrorCode.ERR_BadParameterModifiersOrder, "ref").WithArguments("ref", "this").WithLocation(19, 37),
// (12,21): error CS1106: Extension method must be defined in a non-generic static class
// public static class GenExtensions<X>
Diagnostic(ErrorCode.ERR_BadExtensionAgg, "GenExtensions").WithLocation(12, 21),
// (21,41): error CS8339: The parameter modifier 'ref' cannot be used after the modifier 'this'
// public static void Goo2<T,U,V>(this ref U u) {}
Diagnostic(ErrorCode.ERR_BadParameterModifiersOrder, "ref").WithArguments("ref", "this").WithLocation(21, 41),
// (12,21): error CS1106: Extension method must be defined in a non-generic static class
// public static class GenExtensions<X>
Diagnostic(ErrorCode.ERR_BadExtensionAgg, "GenExtensions").WithLocation(12, 21),
// (15,34): error CS8339: The parameter modifier 'ref' cannot be used after the modifier 'this'
// public static void Goo2(this ref int i) {}
Diagnostic(ErrorCode.ERR_BadParameterModifiersOrder, "ref").WithArguments("ref", "this").WithLocation(15, 34),
// (12,21): error CS1106: Extension method must be defined in a non-generic static class
// public static class GenExtensions<X>
Diagnostic(ErrorCode.ERR_BadExtensionAgg, "GenExtensions").WithLocation(12, 21));
// (7,35): error CS1107: A parameter can only have one 'in' modifier
// public static void M4(in this in int i) {}
Diagnostic(ErrorCode.ERR_DupParamMod, "in").WithArguments("in").WithLocation(7, 35),
// (5,36): error CS8328: The parameter modifier 'in' cannot be used with 'ref'
// public static void M2(ref this in int i) {}
Diagnostic(ErrorCode.ERR_BadParameterModifiers, "in").WithArguments("in", "ref").WithLocation(5, 36),
// (6,35): error CS8328: The parameter modifier 'ref' cannot be used with 'in'
// public static void M3(in this ref int i) {}
Diagnostic(ErrorCode.ERR_BadParameterModifiers, "ref").WithArguments("ref", "in").WithLocation(6, 35),
// (4,36): error CS1107: A parameter can only have one 'ref' modifier
// public static void M1(ref this ref int i) {}
Diagnostic(ErrorCode.ERR_DupParamMod, "ref").WithArguments("ref").WithLocation(4, 36)
);
}
[Fact]
......@@ -3505,7 +3458,7 @@ public class TestType
[Fact]
[CompilerTrait(CompilerFeature.ReadOnlyReferences)]
public void BadInWithThisParameterModifiers()
public void InWithThis_ParameterModifiers()
{
var test = @"
public static class TestType
......@@ -3524,16 +3477,7 @@ public static class TestType
}
";
CreateCompilationWithMscorlibAndSystemCore(test).GetDeclarationDiagnostics().Verify(
// (14,42): error CS8339: The parameter modifier 'in' cannot be used after the modifier 'this'
// public static void Method6<T, U, V>(this in int i) { }
Diagnostic(ErrorCode.ERR_BadParameterModifiersOrder, "in").WithArguments("in", "this").WithLocation(14, 42),
// (6,33): error CS8339: The parameter modifier 'in' cannot be used after the modifier 'this'
// public static void Method2(this in int i) { }
Diagnostic(ErrorCode.ERR_BadParameterModifiersOrder, "in").WithArguments("in", "this").WithLocation(6, 33),
// (10,36): error CS8339: The parameter modifier 'in' cannot be used after the modifier 'this'
// public static void Method4<T>(this in int i) { }
Diagnostic(ErrorCode.ERR_BadParameterModifiersOrder, "in").WithArguments("in", "this").WithLocation(10, 36));
CreateCompilationWithMscorlibAndSystemCore(test).VerifyDiagnostics();
}
[Fact]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册