|
11 | 11 |
|
12 | 12 | struct Struct { }
|
13 | 13 |
|
| 14 | +interface I1 { } |
| 15 | + |
| 16 | +interface I2<M> { } |
| 17 | + |
| 18 | +class ClassWithI1 : I1 { } |
| 19 | + |
| 20 | +class ClassWithI1I2 : I1, I2<ClassWithI1I2> { } |
| 21 | + |
14 | 22 | public static unsafe class UnsafeAccessorsTestsGenerics
|
15 | 23 | {
|
16 | 24 | class ClassWithEnum<T>
|
@@ -396,45 +404,82 @@ public static void Verify_Generic_GenericTypeGenericStaticMethod()
|
396 | 404 | }
|
397 | 405 | }
|
398 | 406 |
|
399 |
| - class ClassWithConstraints |
| 407 | + class MethodWithConstraints |
400 | 408 | {
|
401 |
| - private string M<T, U>() where T : U, IEquatable<T> |
| 409 | + private string M<T, U>() where T : U, I2<T> |
402 | 410 | => $"{typeof(T)}|{typeof(U)}";
|
403 | 411 |
|
404 |
| - private static string SM<T, U>() where T : U, IEquatable<T> |
| 412 | + private static string SM<T, U>() where T : U, I2<T> |
405 | 413 | => $"{typeof(T)}|{typeof(U)}";
|
406 | 414 | }
|
407 | 415 |
|
408 | 416 | [Fact]
|
409 | 417 | [ActiveIssue("https://github.com/dotnet/runtime/issues/102942", TestRuntimes.Mono)]
|
410 |
| - public static void Verify_Generic_ConstraintEnforcement() |
| 418 | + public static void Verify_Generic_MethodConstraintEnforcement() |
411 | 419 | {
|
412 |
| - Console.WriteLine($"Running {nameof(Verify_Generic_ConstraintEnforcement)}"); |
| 420 | + Console.WriteLine($"Running {nameof(Verify_Generic_MethodConstraintEnforcement)}"); |
413 | 421 |
|
414 |
| - Assert.Equal($"{typeof(string)}|{typeof(object)}", CallMethod<string, object>(new ClassWithConstraints())); |
415 |
| - Assert.Equal($"{typeof(string)}|{typeof(object)}", CallStaticMethod<string, object>(null)); |
416 |
| - Assert.Throws<InvalidProgramException>(() => CallMethod_NoConstraints<string, object>(new ClassWithConstraints())); |
417 |
| - Assert.Throws<InvalidProgramException>(() => CallMethod_MissingConstraint<string, object>(new ClassWithConstraints())); |
418 |
| - Assert.Throws<InvalidProgramException>(() => CallStaticMethod_NoConstraints<string, object>(null)); |
419 |
| - Assert.Throws<InvalidProgramException>(() => CallStaticMethod_MissingConstraint<string, object>(null)); |
| 422 | + Assert.Equal($"{typeof(ClassWithI1I2)}|{typeof(I1)}", CallMethod<ClassWithI1I2, I1>(new MethodWithConstraints())); |
| 423 | + Assert.Equal($"{typeof(ClassWithI1I2)}|{typeof(I1)}", CallStaticMethod<ClassWithI1I2, I1>(null)); |
| 424 | + Assert.Throws<InvalidProgramException>(() => CallMethod_NoConstraints<ClassWithI1I2, I1>(new MethodWithConstraints())); |
| 425 | + Assert.Throws<InvalidProgramException>(() => CallMethod_MissingConstraint<ClassWithI1I2, I1>(new MethodWithConstraints())); |
| 426 | + Assert.Throws<InvalidProgramException>(() => CallStaticMethod_NoConstraints<ClassWithI1I2, I1>(null)); |
| 427 | + Assert.Throws<InvalidProgramException>(() => CallStaticMethod_MissingConstraint<ClassWithI1I2, I1>(null)); |
420 | 428 |
|
421 | 429 | [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "M")]
|
422 |
| - extern static string CallMethod<V,W>(ClassWithConstraints c) where V : W, IEquatable<V>; |
| 430 | + extern static string CallMethod<V,W>(MethodWithConstraints c) where V : W, I2<V>; |
423 | 431 |
|
424 | 432 | [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "M")]
|
425 |
| - extern static string CallMethod_NoConstraints<V,W>(ClassWithConstraints c); |
| 433 | + extern static string CallMethod_NoConstraints<V,W>(MethodWithConstraints c); |
426 | 434 |
|
427 | 435 | [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "M")]
|
428 |
| - extern static string CallMethod_MissingConstraint<V,W>(ClassWithConstraints c) where V : W; |
| 436 | + extern static string CallMethod_MissingConstraint<V,W>(MethodWithConstraints c) where V : W; |
429 | 437 |
|
430 | 438 | [UnsafeAccessor(UnsafeAccessorKind.StaticMethod, Name = "SM")]
|
431 |
| - extern static string CallStaticMethod<V,W>(ClassWithConstraints c) where V : W, IEquatable<V>; |
| 439 | + extern static string CallStaticMethod<V,W>(MethodWithConstraints c) where V : W, I2<V>; |
432 | 440 |
|
433 | 441 | [UnsafeAccessor(UnsafeAccessorKind.StaticMethod, Name = "SM")]
|
434 |
| - extern static string CallStaticMethod_NoConstraints<V,W>(ClassWithConstraints c); |
| 442 | + extern static string CallStaticMethod_NoConstraints<V,W>(MethodWithConstraints c); |
435 | 443 |
|
436 | 444 | [UnsafeAccessor(UnsafeAccessorKind.StaticMethod, Name = "SM")]
|
437 |
| - extern static string CallStaticMethod_MissingConstraint<V,W>(ClassWithConstraints c) where V : W; |
| 445 | + extern static string CallStaticMethod_MissingConstraint<V,W>(MethodWithConstraints c) where V : W; |
| 446 | + } |
| 447 | + |
| 448 | + class ClassWithConstraints<T, U> where T : U, I2<T> |
| 449 | + { |
| 450 | + private string M<W>() where W : I1 |
| 451 | + => $"{typeof(T)}|{typeof(U)}|{typeof(W)}"; |
| 452 | + |
| 453 | + private static string SM<X>() where X : I1 |
| 454 | + => $"{typeof(T)}|{typeof(U)}|{typeof(X)}"; |
| 455 | + } |
| 456 | + |
| 457 | + class AccessorsWithConstraints<A, B> where A : B, I2<A> |
| 458 | + { |
| 459 | + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "M")] |
| 460 | + public extern static string CallMethod<C>(ClassWithConstraints<A, B> c) where C: I1; |
| 461 | + |
| 462 | + [UnsafeAccessor(UnsafeAccessorKind.StaticMethod, Name = "SM")] |
| 463 | + public extern static string CallStaticMethod<D>(ClassWithConstraints<A, B> c) where D: I1; |
| 464 | + |
| 465 | + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "M")] |
| 466 | + public extern static string CallMethod_MissingMethodConstraint<E>(ClassWithConstraints<A, B> c); |
| 467 | + |
| 468 | + [UnsafeAccessor(UnsafeAccessorKind.StaticMethod, Name = "SM")] |
| 469 | + public extern static string CallStaticMethod_MissingMethodConstraint<F>(ClassWithConstraints<A, B> c); |
| 470 | + } |
| 471 | + |
| 472 | + [Fact] |
| 473 | + [ActiveIssue("https://github.com/dotnet/runtime/issues/102942", TestRuntimes.Mono)] |
| 474 | + public static void Verify_Generic_ClassConstraintEnforcement() |
| 475 | + { |
| 476 | + Console.WriteLine($"Running {nameof(Verify_Generic_ClassConstraintEnforcement)}"); |
| 477 | + |
| 478 | + Assert.Equal($"{typeof(ClassWithI1I2)}|{typeof(I1)}|{typeof(ClassWithI1)}", AccessorsWithConstraints<ClassWithI1I2, I1>.CallMethod<ClassWithI1>(new ClassWithConstraints<ClassWithI1I2, I1>())); |
| 479 | + Assert.Equal($"{typeof(ClassWithI1I2)}|{typeof(I1)}|{typeof(ClassWithI1)}", AccessorsWithConstraints<ClassWithI1I2, I1>.CallStaticMethod<ClassWithI1>(null)); |
| 480 | + |
| 481 | + Assert.Throws<InvalidProgramException>(() => AccessorsWithConstraints<ClassWithI1I2, I1>.CallMethod_MissingMethodConstraint<ClassWithI1>(new ClassWithConstraints<ClassWithI1I2, I1>())); |
| 482 | + Assert.Throws<InvalidProgramException>(() => AccessorsWithConstraints<ClassWithI1I2, I1>.CallStaticMethod_MissingMethodConstraint<ClassWithI1>(null)); |
438 | 483 | }
|
439 | 484 |
|
440 | 485 | class Invalid
|
|
0 commit comments