未验证 提交 4c0a9ee9 编写于 作者: R Rikki Gibson 提交者: GitHub

Allow unmanaged generic structs (#31148)

* Add unmanaged generic struct tests

* Don't bail out of managed type checks when type arguments are present

* Simplify test

* Delegate HasPointerType to underlying field in WrappedFieldSymbol

* Add test for recursive expansion of struct with T : unmanaged

* Delay constraint checking on field types until after type members are added

* Update comment

* Add expected diagnostic to UnmanagedRecursiveTypeArgument test

* Add unmanaged recursive type argument tests with constraint violations

* Don't search fields whose type is circular struct when determining if a type is managed

* Update some tests

* Use TypeSyntax.Location for Type.CheckAllConstraints

* Add prototype comment

* Update GenericConstraintsTests

* Update IsManagedType asserts in UnsafeTests

* Fix ManagedAddressOfTests.DisallowSizeof

* Use SourceMemberFieldSymbol.SyntaxNode.Location for consistency in diagnostics

* Add some tests and diagnostics

* Fix more tests

* Fix BaseClassTests

* Add test for partially constructed generic struct which violates unmanaged constraint

* Consider nullability when running AfterTypeMembersChecks

* Update NullableReferenceTypesTests.Constraint_Oblivious due to differences from delayed constraint checks on field types

* Check if NRT enabled in compilation to use correct nullability in constraint checks

* Make UnmanagedConstraint_StructMismatchInImplements behave consistently

* Disable ResourceTests.AddResourceToModule in Mono

* Remove prototype comment

* Remove invalid comments from UnmanagedConstraints_NestedInGenericType

* Use ErrorLocation instead of SyntaxNode.Location

* Rename our pipeline YAML files

Originally created when everything was VSTS. This gets us back inline
with the new branding.

* Fix tests now that we use ErrorLocation for field constraint checks
上级 db3a9f3a
phases:
- phase: Windows_VisualStudio_Integration_Tests
queue:
name: dotnet-external-temp-vs2017
timeoutInMinutes: 90
parallel: 2
matrix:
debug:
_configuration: Debug
release:
_configuration: Release
steps:
- script: build/scripts/cibuild.cmd -configuration $(_configuration) -testVsi
displayName: Build and Test
- task: PublishTestResults@1
inputs:
testRunner: XUnit
testResultsFiles: '**/xUnitResults/*.xml'
mergeTestResults: true
testRunTitle: 'Windows Visual Studio Integration $(_configuration)'
condition: succeededOrFailed()
- task: PublishBuildArtifacts@1
displayName: Publish Logs
inputs:
PathtoPublish: '$(Build.SourcesDirectory)\Binaries\$(_configuration)\Logs'
ArtifactName: 'Windows Visual Studio Integration $(_configuration)'
publishLocation: Container
continueOnError: true
condition: or(failed(), canceled())
- task: PublishBuildArtifacts@1
displayName: Publish Screenshots
inputs:
PathtoPublish: '$(Build.SourcesDirectory)\Binaries\$(_configuration)\UnitTests\Microsoft.VisualStudio.LanguageServices.IntegrationTests\xUnitResults/'
ArtifactName: 'Screenshots $(_configuration)'
publishLocation: Container
continueOnError: true
condition: or(failed(), canceled())
......@@ -93,8 +93,7 @@ private static void StructDependsClosure(NamedTypeSymbol type, HashSet<Symbol> p
/// IsManagedType is simple for most named types:
/// enums are not managed;
/// non-enum, non-struct named types are managed;
/// generic types and their nested types are managed;
/// type parameters are managed;
/// type parameters are managed unless an 'unmanaged' constraint is present;
/// all special types have spec'd values (basically, (non-string) primitives) are not managed;
///
/// Only structs are complicated, because the definition is recursive. A struct type is managed
......@@ -184,7 +183,8 @@ private static bool DependsOnDefinitelyManagedType(NamedTypeSymbol type, HashSet
case ThreeState.False:
continue;
case ThreeState.Unknown:
if (DependsOnDefinitelyManagedType(fieldNamedType, partialClosure))
if (!fieldNamedType.OriginalDefinition.KnownCircularStruct &&
DependsOnDefinitelyManagedType(fieldNamedType, partialClosure))
{
return true;
}
......@@ -238,11 +238,6 @@ private static ThreeState IsManagedTypeHelper(NamedTypeSymbol type)
break; // Proceed with additional checks.
}
if (type.AllTypeArgumentCount() > 0)
{
return ThreeState.True;
}
switch (type.TypeKind)
{
case TypeKind.Enum:
......
......@@ -429,7 +429,7 @@ internal sealed override TypeSymbolWithAnnotations GetFieldType(ConsList<FieldSy
var binderFactory = compilation.GetBinderFactory(SyntaxTree);
var binder = binderFactory.GetBinder(typeSyntax);
binder = binder.WithContainingMemberOrLambda(this);
binder = binder.WithAdditionalFlagsAndContainingMemberOrLambda(BinderFlags.SuppressConstraintChecks, this);
if (!ContainingType.IsScriptClass)
{
type = binder.BindType(typeSyntax, diagnosticsForFirstDeclarator);
......@@ -571,5 +571,12 @@ internal override bool IsDefinedInSourceTree(SyntaxTree tree, TextSpan? definedW
return false;
}
internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, DiagnosticBag diagnostics)
{
bool includeNullability = DeclaringCompilation.IsFeatureEnabled(MessageID.IDS_FeatureNullableReferenceTypes);
Type.CheckAllConstraints(conversions.WithNullability(includeNullability), ErrorLocation, diagnostics);
base.AfterAddingTypeMembersChecks(conversions, diagnostics);
}
}
}
......@@ -85,6 +85,8 @@ internal override bool IsNotSerialized
}
}
internal override bool HasPointerType => _underlyingField.HasPointerType;
internal override bool IsMarshalledExplicitly
{
get
......
......@@ -9633,9 +9633,9 @@ class C<T>
// (16,12): error CS0452: The type 'U' must be a reference type in order to use it as parameter 'T2' in the generic type or method 'ValueTuple<T1, T2>'
// (U, U) M<U>(U x)
Diagnostic(ErrorCode.ERR_RefConstraintNotSatisfied, "M").WithArguments("System.ValueTuple<T1, T2>", "T2", "U").WithLocation(16, 12),
// (15,14): error CS0452: The type 'T' must be a reference type in order to use it as parameter 'T2' in the generic type or method 'ValueTuple<T1, T2>'
// (15,18): error CS0452: The type 'T' must be a reference type in order to use it as parameter 'T2' in the generic type or method 'ValueTuple<T1, T2>'
// List<(T, T)> field = null;
Diagnostic(ErrorCode.ERR_RefConstraintNotSatisfied, "T").WithArguments("System.ValueTuple<T1, T2>", "T2", "T").WithLocation(15, 14),
Diagnostic(ErrorCode.ERR_RefConstraintNotSatisfied, "field").WithArguments("System.ValueTuple<T1, T2>", "T2", "T").WithLocation(15, 18),
// (20,28): error CS0452: The type 'U' must be a reference type in order to use it as parameter 'T2' in the generic type or method 'ValueTuple<T1, T2>'
// return default((U, U));
Diagnostic(ErrorCode.ERR_RefConstraintNotSatisfied, "U").WithArguments("System.ValueTuple<T1, T2>", "T2", "U").WithLocation(20, 28),
......@@ -9714,9 +9714,9 @@ class C<T> where T : class
// (16,12): error CS0453: The type 'U' must be a non-nullable value type in order to use it as parameter 'T2' in the generic type or method 'ValueTuple<T1, T2>'
// (U, U) M<U>(U x) where U : class
Diagnostic(ErrorCode.ERR_ValConstraintNotSatisfied, "M").WithArguments("System.ValueTuple<T1, T2>", "T2", "U").WithLocation(16, 12),
// (15,14): error CS0453: The type 'T' must be a non-nullable value type in order to use it as parameter 'T2' in the generic type or method 'ValueTuple<T1, T2>'
// (15,18): error CS0453: The type 'T' must be a non-nullable value type in order to use it as parameter 'T2' in the generic type or method 'ValueTuple<T1, T2>'
// List<(T, T)> field = null;
Diagnostic(ErrorCode.ERR_ValConstraintNotSatisfied, "T").WithArguments("System.ValueTuple<T1, T2>", "T2", "T").WithLocation(15, 14),
Diagnostic(ErrorCode.ERR_ValConstraintNotSatisfied, "field").WithArguments("System.ValueTuple<T1, T2>", "T2", "T").WithLocation(15, 18),
// (18,24): error CS0452: The type 'int' must be a reference type in order to use it as parameter 'T' in the generic type or method 'C<T>'
// var t0 = new C<int>();
Diagnostic(ErrorCode.ERR_RefConstraintNotSatisfied, "int").WithArguments("C<T>", "T", "int").WithLocation(18, 24),
......
......@@ -433,7 +433,7 @@ public void AddManagedResource()
c1 = null;
}
[ConditionalFact(typeof(DesktopOnly))]
[ConditionalFact(typeof(WindowsDesktopOnly))]
public void AddResourceToModule()
{
bool metadataOnly = false;
......
......@@ -2286,6 +2286,10 @@ public class B : A
public void UnmanagedConstraint_StructMismatchInImplements()
{
CreateCompilation(@"
public struct Segment<T> {
public T[] array;
}
public interface I1<in T> where T : unmanaged
{
void Test<G>(G x) where G : unmanaged;
......@@ -2296,22 +2300,22 @@ public class C2<T> : I1<T> where T : struct
public void Test<G>(G x) where G : struct
{
I1<T> i = this;
i.Test(default(System.ArraySegment<int>));
i.Test(default(Segment<int>));
}
}
").VerifyDiagnostics(
// (7,14): error CS8379: The type 'T' must be a non-nullable value type, along with all fields at any level of nesting, in order to use it as parameter 'T' in the generic type or method 'I1<T>'
// (11,14): error CS8377: The type 'T' must be a non-nullable value type, along with all fields at any level of nesting, in order to use it as parameter 'T' in the generic type or method 'I1<T>'
// public class C2<T> : I1<T> where T : struct
Diagnostic(ErrorCode.ERR_UnmanagedConstraintNotSatisfied, "C2").WithArguments("I1<T>", "T", "T").WithLocation(7, 14),
// (9,17): error CS0425: The constraints for type parameter 'G' of method 'C2<T>.Test<G>(G)' must match the constraints for type parameter 'G' of interface method 'I1<T>.Test<G>(G)'. Consider using an explicit interface implementation instead.
Diagnostic(ErrorCode.ERR_UnmanagedConstraintNotSatisfied, "C2").WithArguments("I1<T>", "T", "T").WithLocation(11, 14),
// (13,17): error CS0425: The constraints for type parameter 'G' of method 'C2<T>.Test<G>(G)' must match the constraints for type parameter 'G' of interface method 'I1<T>.Test<G>(G)'. Consider using an explicit interface implementation instead.
// public void Test<G>(G x) where G : struct
Diagnostic(ErrorCode.ERR_ImplBadConstraints, "Test").WithArguments("G", "C2<T>.Test<G>(G)", "G", "I1<T>.Test<G>(G)").WithLocation(9, 17),
// (11,12): error CS8379: The type 'T' must be a non-nullable value type, along with all fields at any level of nesting, in order to use it as parameter 'T' in the generic type or method 'I1<T>'
Diagnostic(ErrorCode.ERR_ImplBadConstraints, "Test").WithArguments("G", "C2<T>.Test<G>(G)", "G", "I1<T>.Test<G>(G)").WithLocation(13, 17),
// (15,12): error CS8377: The type 'T' must be a non-nullable value type, along with all fields at any level of nesting, in order to use it as parameter 'T' in the generic type or method 'I1<T>'
// I1<T> i = this;
Diagnostic(ErrorCode.ERR_UnmanagedConstraintNotSatisfied, "T").WithArguments("I1<T>", "T", "T").WithLocation(11, 12),
// (12,11): error CS8379: The type 'ArraySegment<int>' must be a non-nullable value type, along with all fields at any level of nesting, in order to use it as parameter 'G' in the generic type or method 'I1<T>.Test<G>(G)'
// i.Test(default(System.ArraySegment<int>));
Diagnostic(ErrorCode.ERR_UnmanagedConstraintNotSatisfied, "Test").WithArguments("I1<T>.Test<G>(G)", "G", "System.ArraySegment<int>").WithLocation(12, 11)
Diagnostic(ErrorCode.ERR_UnmanagedConstraintNotSatisfied, "T").WithArguments("I1<T>", "T", "T").WithLocation(15, 12),
// (16,11): error CS8377: The type 'Segment<int>' must be a non-nullable value type, along with all fields at any level of nesting, in order to use it as parameter 'G' in the generic type or method 'I1<T>.Test<G>(G)'
// i.Test(default(Segment<int>));
Diagnostic(ErrorCode.ERR_UnmanagedConstraintNotSatisfied, "Test").WithArguments("I1<T>.Test<G>(G)", "G", "Segment<int>").WithLocation(16, 11)
);
}
......@@ -2976,7 +2980,7 @@ void User()
IsStruct<Wrapper<int>.E>();
IsNew<Wrapper<int>.E>();
IsUnmanaged<Wrapper<int>.S>(); // Invalid
IsUnmanaged<Wrapper<int>.S>();
IsEnum<Wrapper<int>.S>(); // Invalid
IsStruct<Wrapper<int>.S>();
IsNew<Wrapper<int>.S>();
......@@ -2986,7 +2990,7 @@ void User()
IsStruct<Wrapper<string>.E>();
IsNew<Wrapper<string>.E>();
IsUnmanaged<Wrapper<string>.S>(); // Invalid
IsUnmanaged<Wrapper<string>.S>();
IsEnum<Wrapper<string>.S>(); // Invalid
IsStruct<Wrapper<string>.S>();
IsNew<Wrapper<string>.S>();
......@@ -2994,15 +2998,9 @@ void User()
}";
CreateCompilation(code).VerifyDiagnostics(
// (27,9): error CS8377: The type 'Wrapper<int>.S' must be a non-nullable value type, along with all fields at any level of nesting, in order to use it as parameter 'T' in the generic type or method 'Test.IsUnmanaged<T>()'
// IsUnmanaged<Wrapper<int>.S>(); // Invalid
Diagnostic(ErrorCode.ERR_UnmanagedConstraintNotSatisfied, "IsUnmanaged<Wrapper<int>.S>").WithArguments("Test.IsUnmanaged<T>()", "T", "Wrapper<int>.S").WithLocation(27, 9),
// (28,9): error CS0315: The type 'Wrapper<int>.S' cannot be used as type parameter 'T' in the generic type or method 'Test.IsEnum<T>()'. There is no boxing conversion from 'Wrapper<int>.S' to 'System.Enum'.
// IsEnum<Wrapper<int>.S>(); // Invalid
Diagnostic(ErrorCode.ERR_GenericConstraintNotSatisfiedValType, "IsEnum<Wrapper<int>.S>").WithArguments("Test.IsEnum<T>()", "System.Enum", "T", "Wrapper<int>.S").WithLocation(28, 9),
// (37,9): error CS8377: The type 'Wrapper<string>.S' must be a non-nullable value type, along with all fields at any level of nesting, in order to use it as parameter 'T' in the generic type or method 'Test.IsUnmanaged<T>()'
// IsUnmanaged<Wrapper<string>.S>(); // Invalid
Diagnostic(ErrorCode.ERR_UnmanagedConstraintNotSatisfied, "IsUnmanaged<Wrapper<string>.S>").WithArguments("Test.IsUnmanaged<T>()", "T", "Wrapper<string>.S").WithLocation(37, 9),
// (38,9): error CS0315: The type 'Wrapper<string>.S' cannot be used as type parameter 'T' in the generic type or method 'Test.IsEnum<T>()'. There is no boxing conversion from 'Wrapper<string>.S' to 'System.Enum'.
// IsEnum<Wrapper<string>.S>(); // Invalid
Diagnostic(ErrorCode.ERR_GenericConstraintNotSatisfiedValType, "IsEnum<Wrapper<string>.S>").WithArguments("Test.IsEnum<T>()", "System.Enum", "T", "Wrapper<string>.S").WithLocation(38, 9));
......@@ -3270,5 +3268,366 @@ void Test()
// UnmanagedWithInterface(&a); // fail (does not match interface)
Diagnostic(ErrorCode.ERR_GenericConstraintNotSatisfiedValType, "UnmanagedWithInterface").WithArguments("C.UnmanagedWithInterface<T>(T*)", "System.IDisposable", "T", "int").WithLocation(20, 9));
}
[Fact]
public void UnmanagedGenericStructPointer()
{
var code = @"
public struct MyStruct<T>
{
public T field;
}
public class C
{
public unsafe void M()
{
MyStruct<int> myStruct;
M2(&myStruct);
}
public unsafe void M2(MyStruct<int>* ms) { }
}
";
CreateCompilation(code, options: TestOptions.UnsafeReleaseDll)
.VerifyDiagnostics();
}
[Fact]
public void ManagedGenericStructPointer()
{
var code = @"
public struct MyStruct<T>
{
public T field;
}
public class C
{
public unsafe void M()
{
MyStruct<string> myStruct;
M2(&myStruct);
}
public unsafe void M2<T>(MyStruct<T>* ms) where T : unmanaged { }
}
";
CreateCompilation(code, options: TestOptions.UnsafeReleaseDll)
.VerifyDiagnostics(
// (12,12): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('MyStruct<string>')
// M2(&myStruct);
Diagnostic(ErrorCode.ERR_ManagedAddr, "&myStruct").WithArguments("MyStruct<string>").WithLocation(12, 12));
}
[Fact]
public void UnmanagedGenericConstraintStructPointer()
{
var code = @"
public struct MyStruct<T> where T : unmanaged
{
public T field;
}
public class C
{
public unsafe void M()
{
MyStruct<int> myStruct;
M2(&myStruct);
}
public unsafe void M2(MyStruct<int>* ms) { }
}
";
CreateCompilation(code, options: TestOptions.UnsafeReleaseDll)
.VerifyDiagnostics();
}
[Fact]
public void UnmanagedGenericConstraintNestedStructPointer()
{
var code = @"
public struct MyStruct<T> where T : unmanaged
{
public T field;
}
public struct OuterStruct
{
public int x;
public InnerStruct inner;
}
public struct InnerStruct
{
public int y;
}
public class C
{
public unsafe void M()
{
MyStruct<OuterStruct> myStruct;
M2(&myStruct);
}
public unsafe void M2(MyStruct<OuterStruct>* ms) { }
}
";
CreateCompilation(code, options: TestOptions.UnsafeReleaseDll)
.VerifyDiagnostics();
}
[Fact]
public void UnmanagedGenericConstraintNestedGenericStructPointer()
{
var code = @"
public struct MyStruct<T> where T : unmanaged
{
public T field;
}
public struct InnerStruct<U>
{
public U value;
}
public class C
{
public unsafe void M()
{
MyStruct<InnerStruct<int>> myStruct;
M2(&myStruct);
}
public unsafe void M2(MyStruct<InnerStruct<int>>* ms) { }
}
";
CreateCompilation(code, options: TestOptions.UnsafeReleaseDll)
.VerifyDiagnostics();
}
[Fact]
public void UnmanagedGenericConstraintPartialConstructedStruct()
{
var code = @"
public struct MyStruct<T> where T : unmanaged
{
public T field;
}
public class C
{
public unsafe void M<U>()
{
MyStruct<U> myStruct;
M2<U>(&myStruct);
}
public unsafe void M2<V>(MyStruct<V>* ms) { }
}
";
CreateCompilation(code, options: TestOptions.UnsafeReleaseDll)
.VerifyDiagnostics(
// (11,18): error CS8377: The type 'U' must be a non-nullable value type, along with all fields at any level of nesting, in order to use it as parameter 'T' in the generic type or method 'MyStruct<T>'
// MyStruct<U> myStruct;
Diagnostic(ErrorCode.ERR_UnmanagedConstraintNotSatisfied, "U").WithArguments("MyStruct<T>", "T", "U").WithLocation(11, 18),
// (12,15): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('MyStruct<U>')
// M2<U>(&myStruct);
Diagnostic(ErrorCode.ERR_ManagedAddr, "&myStruct").WithArguments("MyStruct<U>").WithLocation(12, 15),
// (15,30): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('MyStruct<V>')
// public unsafe void M2<V>(MyStruct<V>* ms) { }
Diagnostic(ErrorCode.ERR_ManagedAddr, "MyStruct<V>*").WithArguments("MyStruct<V>").WithLocation(15, 30),
// (15,43): error CS8377: The type 'V' must be a non-nullable value type, along with all fields at any level of nesting, in order to use it as parameter 'T' in the generic type or method 'MyStruct<T>'
// public unsafe void M2<V>(MyStruct<V>* ms) { }
Diagnostic(ErrorCode.ERR_UnmanagedConstraintNotSatisfied, "ms").WithArguments("MyStruct<T>", "T", "V").WithLocation(15, 43));
}
[Fact]
public void GenericStructManagedFieldPointer()
{
var code = @"
public struct MyStruct<T>
{
public T field;
}
public class C
{
public unsafe void M()
{
MyStruct<string> myStruct;
M2(&myStruct);
}
public unsafe void M2(MyStruct<string>* ms) { }
}
";
CreateCompilation(code, options: TestOptions.UnsafeReleaseDll)
.VerifyDiagnostics(
// (12,12): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('MyStruct<string>')
// M2(&myStruct);
Diagnostic(ErrorCode.ERR_ManagedAddr, "&myStruct").WithArguments("MyStruct<string>").WithLocation(12, 12),
// (15,27): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('MyStruct<string>')
// public unsafe void M2(MyStruct<string>* ms) { }
Diagnostic(ErrorCode.ERR_ManagedAddr, "MyStruct<string>*").WithArguments("MyStruct<string>").WithLocation(15, 27));
}
[Fact]
public void UnmanagedRecursiveGenericStruct()
{
var code = @"
public unsafe struct MyStruct<T> where T : unmanaged
{
public YourStruct<T>* field;
}
public unsafe struct YourStruct<T> where T : unmanaged
{
public MyStruct<T>* field;
}
";
CreateCompilation(code, options: TestOptions.UnsafeReleaseDll)
.VerifyDiagnostics();
}
[Fact]
public void UnmanagedRecursiveStruct()
{
var code = @"
public unsafe struct MyStruct
{
public YourStruct* field;
}
public unsafe struct YourStruct
{
public MyStruct* field;
}
";
CreateCompilation(code, options: TestOptions.UnsafeReleaseDll)
.VerifyDiagnostics();
}
[Fact]
public void UnmanagedExpandingTypeArgument()
{
var code = @"
public struct MyStruct<T>
{
public YourStruct<MyStruct<MyStruct<T>>> field;
}
public struct YourStruct<T> where T : unmanaged
{
public T field;
}
";
CreateCompilation(code, options: TestOptions.UnsafeReleaseDll)
.VerifyDiagnostics(
// (4,46): error CS0523: Struct member 'MyStruct<T>.field' of type 'YourStruct<MyStruct<MyStruct<T>>>' causes a cycle in the struct layout
// public YourStruct<MyStruct<MyStruct<T>>> field;
Diagnostic(ErrorCode.ERR_StructLayoutCycle, "field").WithArguments("MyStruct<T>.field", "YourStruct<MyStruct<MyStruct<T>>>").WithLocation(4, 46));
}
[Fact]
public void UnmanagedCyclic()
{
var code = @"
public struct MyStruct<T>
{
public YourStruct<T> field;
}
public struct YourStruct<T> where T : unmanaged
{
public MyStruct<T> field;
}
";
CreateCompilation(code, options: TestOptions.UnsafeReleaseDll)
.VerifyDiagnostics(
// (4,26): error CS0523: Struct member 'MyStruct<T>.field' of type 'YourStruct<T>' causes a cycle in the struct layout
// public YourStruct<T> field;
Diagnostic(ErrorCode.ERR_StructLayoutCycle, "field").WithArguments("MyStruct<T>.field", "YourStruct<T>").WithLocation(4, 26),
// (4,26): error CS8377: The type 'T' must be a non-nullable value type, along with all fields at any level of nesting, in order to use it as parameter 'T' in the generic type or method 'YourStruct<T>'
// public YourStruct<T> field;
Diagnostic(ErrorCode.ERR_UnmanagedConstraintNotSatisfied, "field").WithArguments("YourStruct<T>", "T", "T").WithLocation(4, 26),
// (9,24): error CS0523: Struct member 'YourStruct<T>.field' of type 'MyStruct<T>' causes a cycle in the struct layout
// public MyStruct<T> field;
Diagnostic(ErrorCode.ERR_StructLayoutCycle, "field").WithArguments("YourStruct<T>.field", "MyStruct<T>").WithLocation(9, 24));
}
[Fact]
public void UnmanagedExpandingTypeArgumentManagedGenericField()
{
var code = @"
public struct MyStruct<T>
{
public YourStruct<MyStruct<MyStruct<T>>> field;
public T myField;
}
public struct YourStruct<T> where T : unmanaged
{
public T field;
}
";
CreateCompilation(code, options: TestOptions.UnsafeReleaseDll)
.VerifyDiagnostics(
// (4,46): error CS0523: Struct member 'MyStruct<T>.field' of type 'YourStruct<MyStruct<MyStruct<T>>>' causes a cycle in the struct layout
// public YourStruct<MyStruct<MyStruct<T>>> field;
Diagnostic(ErrorCode.ERR_StructLayoutCycle, "field").WithArguments("MyStruct<T>.field", "YourStruct<MyStruct<MyStruct<T>>>").WithLocation(4, 46));
}
[Fact]
public void UnmanagedExpandingTypeArgumentConstraintViolation()
{
var code = @"
public struct MyStruct<T>
{
public YourStruct<MyStruct<MyStruct<T>>> field;
public string s;
}
public struct YourStruct<T> where T : unmanaged
{
public T field;
}
";
CreateCompilation(code, options: TestOptions.UnsafeReleaseDll)
.VerifyDiagnostics(
// (4,46): error CS0523: Struct member 'MyStruct<T>.field' of type 'YourStruct<MyStruct<MyStruct<T>>>' causes a cycle in the struct layout
// public YourStruct<MyStruct<MyStruct<T>>> field;
Diagnostic(ErrorCode.ERR_StructLayoutCycle, "field").WithArguments("MyStruct<T>.field", "YourStruct<MyStruct<MyStruct<T>>>").WithLocation(4, 46),
// (4,46): error CS8377: The type 'MyStruct<MyStruct<T>>' must be a non-nullable value type, along with all fields at any level of nesting, in order to use it as parameter 'T' in the generic type or method 'YourStruct<T>'
// public YourStruct<MyStruct<MyStruct<T>>> field;
Diagnostic(ErrorCode.ERR_UnmanagedConstraintNotSatisfied, "field").WithArguments("YourStruct<T>", "T", "MyStruct<MyStruct<T>>").WithLocation(4, 46));
}
[Fact]
public void UnmanagedRecursiveTypeArgumentConstraintViolation_02()
{
var code = @"
public struct MyStruct<T>
{
public YourStruct<MyStruct<MyStruct<T>>> field;
}
public struct YourStruct<T> where T : unmanaged
{
public T field;
public string s;
}
";
CreateCompilation(code, options: TestOptions.UnsafeReleaseDll)
.VerifyDiagnostics(
// (4,46): error CS0523: Struct member 'MyStruct<T>.field' of type 'YourStruct<MyStruct<MyStruct<T>>>' causes a cycle in the struct layout
// public YourStruct<MyStruct<MyStruct<T>>> field;
Diagnostic(ErrorCode.ERR_StructLayoutCycle, "field").WithArguments("MyStruct<T>.field", "YourStruct<MyStruct<MyStruct<T>>>").WithLocation(4, 46),
// (4,46): error CS8377: The type 'MyStruct<MyStruct<T>>' must be a non-nullable value type, along with all fields at any level of nesting, in order to use it as parameter 'T' in the generic type or method 'YourStruct<T>'
// public YourStruct<MyStruct<MyStruct<T>>> field;
Diagnostic(ErrorCode.ERR_UnmanagedConstraintNotSatisfied, "field").WithArguments("YourStruct<T>", "T", "MyStruct<MyStruct<T>>").WithLocation(4, 46));
}
}
}
......@@ -50121,9 +50121,6 @@ class D
// (4,24): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' context.
// class B1<T> where T : A? { }
Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(4, 24),
// (21,8): warning CS8631: The type 'A?' cannot be used as type parameter 'T' in the generic type or method 'B4<T>'. Nullability of type argument 'A?' doesn't match constraint type 'A'.
// B4<A?> F9; // 5 and 6
Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "A?").WithArguments("B4<T>", "A", "T", "A?").WithLocation(21, 8),
// (15,9): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' context.
// B1<A?> F3; // 2
Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(15, 9),
......@@ -50139,9 +50136,12 @@ class D
// (13,9): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' context.
// B0<A?> F1; // 1
Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(13, 9),
// (35,8): warning CS8631: The type 'A?' cannot be used as type parameter 'T' in the generic type or method 'B4<T>'. Nullability of type argument 'A?' doesn't match constraint type 'A'.
// (21,12): warning CS8631: The type 'A?' cannot be used as type parameter 'T' in the generic type or method 'B4<T>'. Nullability of type argument 'A?' doesn't match constraint type 'A'.
// B4<A?> F9; // 5 and 6
Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "F9").WithArguments("B4<T>", "A", "T", "A?").WithLocation(21, 12),
// (35,12): warning CS8631: The type 'A?' cannot be used as type parameter 'T' in the generic type or method 'B4<T>'. Nullability of type argument 'A?' doesn't match constraint type 'A'.
// B4<A?> G9; // 7
Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "A?").WithArguments("B4<T>", "A", "T", "A?").WithLocation(35, 8)
Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "G9").WithArguments("B4<T>", "A", "T", "A?").WithLocation(35, 12)
);
}
......@@ -50213,18 +50213,18 @@ class D
// (13,16): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' context.
// B0<A<object?>> F1; // 1
Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(13, 16),
// (30,8): warning CS8631: The type 'A<object>' cannot be used as type parameter 'T' in the generic type or method 'B1<T>'. Nullability of type argument 'A<object>' doesn't match constraint type 'A<object?>'.
// (21,20): warning CS8631: The type 'A<object?>' cannot be used as type parameter 'T' in the generic type or method 'B4<T>'. Nullability of type argument 'A<object?>' doesn't match constraint type 'A<object>'.
// B4<A<object?>> F9; // 5 and 6
Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "F9").WithArguments("B4<T>", "A<object>", "T", "A<object?>").WithLocation(21, 20),
// (30,19): warning CS8631: The type 'A<object>' cannot be used as type parameter 'T' in the generic type or method 'B1<T>'. Nullability of type argument 'A<object>' doesn't match constraint type 'A<object?>'.
// B1<A<object>> G4; // 7
Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "A<object>").WithArguments("B1<T>", "A<object?>", "T", "A<object>").WithLocation(30, 8),
// (34,8): warning CS8631: The type 'A<object>' cannot be used as type parameter 'T' in the generic type or method 'B3<T>'. Nullability of type argument 'A<object>' doesn't match constraint type 'A<object?>'.
Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "G4").WithArguments("B1<T>", "A<object?>", "T", "A<object>").WithLocation(30, 19),
// (34,19): warning CS8631: The type 'A<object>' cannot be used as type parameter 'T' in the generic type or method 'B3<T>'. Nullability of type argument 'A<object>' doesn't match constraint type 'A<object?>'.
// B3<A<object>> G8; // 8
Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "A<object>").WithArguments("B3<T>", "A<object?>", "T", "A<object>").WithLocation(34, 8),
// (35,8): warning CS8631: The type 'A<object?>' cannot be used as type parameter 'T' in the generic type or method 'B4<T>'. Nullability of type argument 'A<object?>' doesn't match constraint type 'A<object>'.
Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "G8").WithArguments("B3<T>", "A<object?>", "T", "A<object>").WithLocation(34, 19),
// (35,20): warning CS8631: The type 'A<object?>' cannot be used as type parameter 'T' in the generic type or method 'B4<T>'. Nullability of type argument 'A<object?>' doesn't match constraint type 'A<object>'.
// B4<A<object?>> G9; // 9
Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "A<object?>").WithArguments("B4<T>", "A<object>", "T", "A<object?>").WithLocation(35, 8),
// (21,8): warning CS8631: The type 'A<object?>' cannot be used as type parameter 'T' in the generic type or method 'B4<T>'. Nullability of type argument 'A<object?>' doesn't match constraint type 'A<object>'.
// B4<A<object?>> F9; // 5 and 6
Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "A<object?>").WithArguments("B4<T>", "A<object>", "T", "A<object?>").WithLocation(21, 8)
Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "G9").WithArguments("B4<T>", "A<object>", "T", "A<object?>").WithLocation(35, 20)
);
}
......@@ -7801,106 +7801,28 @@ unsafe class C
I* i;
C* c;
}";
CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(
// (7,5): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('object')
// object* _object;
Diagnostic(ErrorCode.ERR_ManagedAddr, "object*").WithArguments("object"),
// (22,5): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('string')
// string* _string;
Diagnostic(ErrorCode.ERR_ManagedAddr, "string*").WithArguments("string"),
// (26,5): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('int?')
// int?* _nullable;
Diagnostic(ErrorCode.ERR_ManagedAddr, "int?*").WithArguments("int?"),
// (27,5): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('dynamic')
// dynamic* _dynamic;
Diagnostic(ErrorCode.ERR_ManagedAddr, "dynamic*").WithArguments("dynamic"),
// (29,5): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('D')
// D* d;
Diagnostic(ErrorCode.ERR_ManagedAddr, "D*").WithArguments("D"),
// (31,5): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('I')
// I* i;
Diagnostic(ErrorCode.ERR_ManagedAddr, "I*").WithArguments("I"),
// (32,5): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C')
// C* c;
Diagnostic(ErrorCode.ERR_ManagedAddr, "C*").WithArguments("C"),
// (7,13): warning CS0169: The field 'C._object' is never used
// object* _object;
Diagnostic(ErrorCode.WRN_UnreferencedField, "_object").WithArguments("C._object"),
// (8,11): warning CS0169: The field 'C._void' is never used
// void* _void;
Diagnostic(ErrorCode.WRN_UnreferencedField, "_void").WithArguments("C._void"),
// (9,11): warning CS0169: The field 'C._bool' is never used
// bool* _bool;
Diagnostic(ErrorCode.WRN_UnreferencedField, "_bool").WithArguments("C._bool"),
// (10,11): warning CS0169: The field 'C._char' is never used
// char* _char;
Diagnostic(ErrorCode.WRN_UnreferencedField, "_char").WithArguments("C._char"),
// (11,12): warning CS0169: The field 'C._sbyte' is never used
// sbyte* _sbyte;
Diagnostic(ErrorCode.WRN_UnreferencedField, "_sbyte").WithArguments("C._sbyte"),
// (12,11): warning CS0169: The field 'C._byte' is never used
// byte* _byte;
Diagnostic(ErrorCode.WRN_UnreferencedField, "_byte").WithArguments("C._byte"),
// (13,12): warning CS0169: The field 'C._short' is never used
// short* _short;
Diagnostic(ErrorCode.WRN_UnreferencedField, "_short").WithArguments("C._short"),
// (14,13): warning CS0169: The field 'C._ushort' is never used
// ushort* _ushort;
Diagnostic(ErrorCode.WRN_UnreferencedField, "_ushort").WithArguments("C._ushort"),
// (15,10): warning CS0169: The field 'C._int' is never used
// int* _int;
Diagnostic(ErrorCode.WRN_UnreferencedField, "_int").WithArguments("C._int"),
// (16,11): warning CS0169: The field 'C._uint' is never used
// uint* _uint;
Diagnostic(ErrorCode.WRN_UnreferencedField, "_uint").WithArguments("C._uint"),
// (17,11): warning CS0169: The field 'C._long' is never used
// long* _long;
Diagnostic(ErrorCode.WRN_UnreferencedField, "_long").WithArguments("C._long"),
// (18,12): warning CS0169: The field 'C._ulong' is never used
// ulong* _ulong;
Diagnostic(ErrorCode.WRN_UnreferencedField, "_ulong").WithArguments("C._ulong"),
// (19,14): warning CS0169: The field 'C._decimal' is never used
// decimal* _decimal;
Diagnostic(ErrorCode.WRN_UnreferencedField, "_decimal").WithArguments("C._decimal"),
// (20,12): warning CS0169: The field 'C._float' is never used
// float* _float;
Diagnostic(ErrorCode.WRN_UnreferencedField, "_float").WithArguments("C._float"),
// (21,13): warning CS0169: The field 'C._double' is never used
// double* _double;
Diagnostic(ErrorCode.WRN_UnreferencedField, "_double").WithArguments("C._double"),
// (22,13): warning CS0169: The field 'C._string' is never used
// string* _string;
Diagnostic(ErrorCode.WRN_UnreferencedField, "_string").WithArguments("C._string"),
// (23,20): warning CS0169: The field 'C._intptr' is never used
// System.IntPtr* _intptr;
Diagnostic(ErrorCode.WRN_UnreferencedField, "_intptr").WithArguments("C._intptr"),
// (24,21): warning CS0169: The field 'C._uintptr' is never used
// System.UIntPtr* _uintptr;
Diagnostic(ErrorCode.WRN_UnreferencedField, "_uintptr").WithArguments("C._uintptr"),
// (25,11): warning CS0169: The field 'C._intptr2' is never used
// int** _intptr2;
Diagnostic(ErrorCode.WRN_UnreferencedField, "_intptr2").WithArguments("C._intptr2"),
// (26,11): warning CS0169: The field 'C._nullable' is never used
// int?* _nullable;
Diagnostic(ErrorCode.WRN_UnreferencedField, "_nullable").WithArguments("C._nullable"),
// (27,14): warning CS0169: The field 'C._dynamic' is never used
// dynamic* _dynamic;
Diagnostic(ErrorCode.WRN_UnreferencedField, "_dynamic").WithArguments("C._dynamic"),
// (28,8): warning CS0169: The field 'C.e' is never used
// E* e;
Diagnostic(ErrorCode.WRN_UnreferencedField, "e").WithArguments("C.e"),
// (29,8): warning CS0169: The field 'C.d' is never used
// D* d;
Diagnostic(ErrorCode.WRN_UnreferencedField, "d").WithArguments("C.d"),
// (30,8): warning CS0169: The field 'C.s' is never used
// S* s;
Diagnostic(ErrorCode.WRN_UnreferencedField, "s").WithArguments("C.s"),
// (31,8): warning CS0169: The field 'C.i' is never used
// I* i;
Diagnostic(ErrorCode.WRN_UnreferencedField, "i").WithArguments("C.i"),
// (32,8): warning CS0169: The field 'C.c' is never used
// C* c;
Diagnostic(ErrorCode.WRN_UnreferencedField, "c").WithArguments("C.c"));
CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.UnsafeReleaseDll)
.GetDiagnostics()
.Where(d => d.Severity == DiagnosticSeverity.Error)
.Verify(
// (7,5): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('object')
// object* _object;
Diagnostic(ErrorCode.ERR_ManagedAddr, "object*").WithArguments("object"),
// (22,5): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('string')
// string* _string;
Diagnostic(ErrorCode.ERR_ManagedAddr, "string*").WithArguments("string"),
// (27,5): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('dynamic')
// dynamic* _dynamic;
Diagnostic(ErrorCode.ERR_ManagedAddr, "dynamic*").WithArguments("dynamic"),
// (29,5): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('D')
// D* d;
Diagnostic(ErrorCode.ERR_ManagedAddr, "D*").WithArguments("D"),
// (31,5): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('I')
// I* i;
Diagnostic(ErrorCode.ERR_ManagedAddr, "I*").WithArguments("I"),
// (32,5): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C')
// C* c;
Diagnostic(ErrorCode.ERR_ManagedAddr, "C*").WithArguments("C"));
}
[Fact]
......
......@@ -276,28 +276,15 @@ unsafe class C<T>
";
var compilation = CreateCompilation(text, options: TestOptions.UnsafeReleaseDll);
compilation.VerifyDiagnostics(
// (8,7): error CS0306: The type 'int*' may not be used as a type argument
Diagnostic(ErrorCode.ERR_BadTypeArgument, "int*").WithArguments("int*"),
// (9,7): error CS0306: The type 'int**' may not be used as a type argument
Diagnostic(ErrorCode.ERR_BadTypeArgument, "int**").WithArguments("int**"),
// (4,10): warning CS0169: The field 'C<T>.f0' is never used
Diagnostic(ErrorCode.WRN_UnreferencedField, "f0").WithArguments("C<T>.f0"),
// (5,11): warning CS0169: The field 'C<T>.f1' is never used
Diagnostic(ErrorCode.WRN_UnreferencedField, "f1").WithArguments("C<T>.f1"),
// (6,12): warning CS0169: The field 'C<T>.f2' is never used
Diagnostic(ErrorCode.WRN_UnreferencedField, "f2").WithArguments("C<T>.f2"),
// (7,14): warning CS0169: The field 'C<T>.f3' is never used
Diagnostic(ErrorCode.WRN_UnreferencedField, "f3").WithArguments("C<T>.f3"),
// (8,13): warning CS0169: The field 'C<T>.f4' is never used
Diagnostic(ErrorCode.WRN_UnreferencedField, "f4").WithArguments("C<T>.f4"),
// (9,14): warning CS0169: The field 'C<T>.f5' is never used
Diagnostic(ErrorCode.WRN_UnreferencedField, "f5").WithArguments("C<T>.f5"),
// (10,15): warning CS0169: The field 'C<T>.f6' is never used
Diagnostic(ErrorCode.WRN_UnreferencedField, "f6").WithArguments("C<T>.f6"),
// (11,17): warning CS0169: The field 'C<T>.f7' is never used
Diagnostic(ErrorCode.WRN_UnreferencedField, "f7").WithArguments("C<T>.f7"));
compilation.GetDiagnostics()
.Where(d => d.Severity == DiagnosticSeverity.Error)
.Verify(
// (8,13): error CS0306: The type 'int*' may not be used as a type argument
// C<int*> f4;
Diagnostic(ErrorCode.ERR_BadTypeArgument, "f4").WithArguments("int*").WithLocation(8, 13),
// (9,14): error CS0306: The type 'int**' may not be used as a type argument
// C<int**> f5;
Diagnostic(ErrorCode.ERR_BadTypeArgument, "f5").WithArguments("int**").WithLocation(9, 14));
var type = compilation.GlobalNamespace.GetMember<NamedTypeSymbol>("C");
......@@ -2485,13 +2472,15 @@ class C
object f1;
string f2;
System.Collections.IEnumerable f3;
int? f4;
}
";
var compilation = CreateCompilation(text);
var type = compilation.GlobalNamespace.GetMember<NamedTypeSymbol>("C");
Assert.True(type.GetMembers().OfType<FieldSymbol>().All(field => field.Type.IsManagedType));
foreach (var field in type.GetMembers().OfType<FieldSymbol>())
{
Assert.True(field.Type.IsManagedType, field.ToString());
}
}
[Fact]
......@@ -2514,7 +2503,8 @@ class C
float f12;
double f13;
System.IntPtr f14;
System.UIntPtr f14;
System.UIntPtr f15;
int? f16;
}
";
var compilation = CreateCompilation(text);
......@@ -2605,11 +2595,11 @@ struct S { }
var compilation = CreateCompilation(text);
var globalNamespace = compilation.GlobalNamespace;
Assert.False(globalNamespace.GetMember<NamedTypeSymbol>("S").IsManagedType);
Assert.True(globalNamespace.GetMember<NamedTypeSymbol>("P").IsManagedType);
Assert.False(globalNamespace.GetMember<NamedTypeSymbol>("P").IsManagedType);
Assert.False(globalNamespace.GetMember<NamedTypeSymbol>("C").GetMember<NamedTypeSymbol>("S").IsManagedType);
Assert.True(globalNamespace.GetMember<NamedTypeSymbol>("D").GetMember<NamedTypeSymbol>("S").IsManagedType);
Assert.False(globalNamespace.GetMember<NamedTypeSymbol>("D").GetMember<NamedTypeSymbol>("S").IsManagedType);
Assert.False(globalNamespace.GetMember<NamedTypeSymbol>("Q").GetMember<NamedTypeSymbol>("S").IsManagedType);
Assert.True(globalNamespace.GetMember<NamedTypeSymbol>("R").GetMember<NamedTypeSymbol>("S").IsManagedType);
Assert.False(globalNamespace.GetMember<NamedTypeSymbol>("R").GetMember<NamedTypeSymbol>("S").IsManagedType);
}
[Fact]
......@@ -2631,8 +2621,10 @@ struct R { }
";
var compilation = CreateCompilation(text);
var type = compilation.GlobalNamespace.GetMember<NamedTypeSymbol>("C");
Assert.True(type.GetMembers().OfType<FieldSymbol>().All(field => field.Type.IsManagedType));
Assert.False(type.GetMember<FieldSymbol>("f1").Type.IsManagedType);
Assert.False(type.GetMember<FieldSymbol>("f2").Type.IsManagedType);
Assert.True(type.GetMember<FieldSymbol>("f3").Type.IsManagedType);
Assert.True(type.GetMember<FieldSymbol>("f4").Type.IsManagedType);
}
[Fact]
......@@ -2831,7 +2823,7 @@ struct W<T> { X<W<W<T>>> x; }
var compilation = CreateCompilation(text);
var globalNamespace = compilation.GlobalNamespace;
Assert.True(globalNamespace.GetMember<NamedTypeSymbol>("X").IsManagedType); // because of X.t
Assert.True(globalNamespace.GetMember<NamedTypeSymbol>("W").IsManagedType);
Assert.False(globalNamespace.GetMember<NamedTypeSymbol>("W").IsManagedType);
}
[Fact]
......@@ -7851,10 +7843,7 @@ internal struct Struct1<U> {}
unsafe void NMethodCecilNameHelper_Parameter_AllTogether<U>(ref Goo3.Struct1<int>**[][,,] ppi) { }
}
";
CreateCompilation(text, options: TestOptions.UnsafeDebugDll).VerifyDiagnostics(
// (8,67): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C.Goo3.Struct1<int>')
// unsafe void NMethodCecilNameHelper_Parameter_AllTogether<U>(ref Goo3.Struct1<int>**[][,,] ppi) { }
Diagnostic(ErrorCode.ERR_ManagedAddr, "Goo3.Struct1<int>*").WithArguments("C.Goo3.Struct1<int>").WithLocation(8, 67));
CreateCompilation(text, options: TestOptions.UnsafeDebugDll).VerifyDiagnostics();
}
......
......@@ -1727,21 +1727,21 @@ static void F(I<int> x)
public class D : I<int> {}
public interface I2 : I<int> {}";
CreateCompilationWithILAndMscorlib40(csharp, il, appendDefaultHeader: false).VerifyDiagnostics(
// (4,26): error CS0648: 'I<int>' is a type not supported by the language
// static void F(I<int> x)
Diagnostic(ErrorCode.ERR_BogusType, "x").WithArguments("I<int>").WithLocation(4, 26),
// (3,26): error CS0648: 'I<int>' is a type not supported by the language
// public static I<int> x;
Diagnostic(ErrorCode.ERR_BogusType, "x").WithArguments("I<int>").WithLocation(3, 26),
// (10,14): error CS0648: 'I<int>' is a type not supported by the language
// public class D : I<int> {}
Diagnostic(ErrorCode.ERR_BogusType, "D").WithArguments("I<int>"),
Diagnostic(ErrorCode.ERR_BogusType, "D").WithArguments("I<int>").WithLocation(10, 14),
// (11,18): error CS0648: 'I<int>' is a type not supported by the language
// public interface I2 : I<int> {}
Diagnostic(ErrorCode.ERR_BogusType, "I2").WithArguments("I<int>"),
// (4,26): error CS0648: 'I<int>' is a type not supported by the language
// static void F(I<int> x)
Diagnostic(ErrorCode.ERR_BogusType, "x").WithArguments("I<int>"),
// (3,19): error CS0648: 'I<int>' is a type not supported by the language
// public static I<int> x;
Diagnostic(ErrorCode.ERR_BogusType, "I<int>").WithArguments("I<int>"),
Diagnostic(ErrorCode.ERR_BogusType, "I2").WithArguments("I<int>").WithLocation(11, 18),
// (6,9): error CS0648: 'I<int>' is a type not supported by the language
// I<int> t = C.x;
Diagnostic(ErrorCode.ERR_BogusType, "I<int>").WithArguments("I<int>")
Diagnostic(ErrorCode.ERR_BogusType, "I<int>").WithArguments("I<int>").WithLocation(6, 9)
);
}
......@@ -1783,13 +1783,13 @@ static void F(I<dynamic> x)
CreateCompilationWithILAndMscorlib40(csharp, il, appendDefaultHeader: false, targetFramework: TargetFramework.Standard).VerifyDiagnostics(
// (4,30): error CS0648: 'I<dynamic>' is a type not supported by the language
// static void F(I<dynamic> x)
Diagnostic(ErrorCode.ERR_BogusType, "x").WithArguments("I<dynamic>"),
// (3,19): error CS0648: 'I<dynamic>' is a type not supported by the language
Diagnostic(ErrorCode.ERR_BogusType, "x").WithArguments("I<dynamic>").WithLocation(4, 30),
// (3,30): error CS0648: 'I<dynamic>' is a type not supported by the language
// public static I<dynamic> x;
Diagnostic(ErrorCode.ERR_BogusType, "I<dynamic>").WithArguments("I<dynamic>"),
Diagnostic(ErrorCode.ERR_BogusType, "x").WithArguments("I<dynamic>").WithLocation(3, 30),
// (6,9): error CS0648: 'I<dynamic>' is a type not supported by the language
// I<dynamic> t = C.x;
Diagnostic(ErrorCode.ERR_BogusType, "I<dynamic>").WithArguments("I<dynamic>")
Diagnostic(ErrorCode.ERR_BogusType, "I<dynamic>").WithArguments("I<dynamic>").WithLocation(6, 9)
);
}
......
......@@ -141,10 +141,6 @@ enum E
{
A
}
struct Generic<T>
{
}
";
var comp = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(comp, runtime =>
......@@ -158,7 +154,6 @@ struct Generic<T>
"I", // interface
"T", // type parameter
"int[]",
"Generic<int>",
"dynamic",
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册