Skip to content

Test Plan for "Ref Struct Interfaces" feature #72124

@AlekseyTs

Description

@AlekseyTs

Championed proposal: dotnet/csharplang#7608
Speclet: https://github.com/dotnet/csharplang/blob/main/proposals/csharp-13.0/ref-struct-interfaces.md
Feature branch: https://github.com/dotnet/roslyn/tree/features/RefStructInterfaces

Compiler

  • language version
    • interface implementation
    • allows ref struct
    • generic type substitution
    • using, foreach, etc. with ref like type interface implementation
  • target runtime support: RuntimeFeature.ByRefLikeGenerics
    • allows ref struct
  • ref struct interface implementation
    • implicit / explicit implementation
    • default interface methods, properties, indexers, events, with virtual / sealed modifiers (see *_DefaultImplementation)
  • allows ref struct constraint (see AllowsConstraint_*)
    • must be last
    • duplicated constraint
    • with struct, class, new(), unmanaged, notnull, default, interface, class
    • on partial type / method
    • on override
    • on implicit / explicit implementation
    • constraint emitted to metadata
    • constraint emitted to ref assembly (Fill some gaps in Test Plan for "Ref Struct Interfaces" feature #74389, AllowsConstraint_01_SimpleTypeTypeParameter)
  • calling instance members on value of type parameter with allows ref struct
    • error calling System.Object methods
    • error calling non-virtual default interface member (ERR_BadNonVirtualInterfaceMemberAccessOnAllowsRefLike error CS9246: A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct.)
    • (open design question) warning calling virtual, non-abstract default interface member
  • conversions
    • from: ref struct
    • from: type parameter with allows ref struct, with/without struct constraint
    • from: implemented/unimplemented interface
    • to: System.Object
    • to: ref struct
    • to: implemented/unimplemented interface
    • to: same type parameter (IdentityConversion_01 .. IdentityConversion_04)
    • to: type parameter with/without allows ref struct, with/without struct constraint
    • to: type parameter with allows ref struct, with/without struct constraint, with implemented interface constraint
    • to: type parameter with allows ref struct, with/without struct constraint, with unimplemented interface constraint
    • to: type parameter with/without allows ref struct, with/without struct constraint, where T : U/where U : T`
  • is operator: value is Type (see IsOperator_*)
    • value: ref struct with/without interface implementation
    • value: interface
    • value: type parameter with/without allows ref struct, with/without struct constraint, with/without interface constraint
    • type: ref struct
    • type: interface
    • type: same type parameter
    • type: type parameter with/without allows ref struct, with/without struct constraint, with/without interface constraint
    • type: type parameter with class constraint, with/without interface constraint (Fill some gaps in Test Plan for "Ref Struct Interfaces" feature #74389, IsOperator_05, IsOperator_07)
    • type: type parameter with/without allows ref struct, with/without struct constraint, where T : U/where U : T`
  • is pattern: value is Type t (see IsPattern_*)
    • see cases from is operator above
  • as operator: value as Type (see AsOperator_*)
    • see cases from is operator above
  • generic type substitution
  • field / auto-property using type parameter with allows ref struct
    • instance field / auto-propertyin ref struct (allowed)
    • instance field / auto-propertyin struct, class (disallowed)
    • static field / auto-property (disallowed)
    • record primary constructor parameter (disallowed)
    • ref struct primary constructor parameter (disallowed)
  • using type parameter with allows ref struct (extend IsRefLikeType checks)
    • value in anonymous type initializer (disallowed)
    • in LINQ query with implicit anonymous type
    • value in makeref (disallowed)
    • type of ref field (disallowed)
    • array element type (disallowed)
    • inline array element type (disallowed)
    • async parameter type (disallowed)
    • value in expression tree (disallowed)
    • delegate receiver (disallowed)
    • conditional access ?. result type, with struct constraint (disallowed)
    • conditional access ?. receiver type, without struct constraint
    • type argument to dynamic call (disallowed)
    • receiver to dynamic call (disallowed)
    • captured in lambda or local function (disallowed)
    • error for method signature with T? when where T : struct, allows ref struct (ConstraintsCheck_06)
  • ref safety analysis for instance of allows ref struct (extend IsRefLikeType checks)
    • new T() instance
    • scoped T instance
    • cannot assign instance to static field (Field, AutoProperty ?)
    • cannot create T[] (InArrayType_01)
    • return only scope (see Return*)
    • method arguments must match (see MethodArgumentsMustMatch_*)
  • null checking with value of type parameter with allows ref struct (see NullCheck_*)
    • value == null, value != null, !(value == null), !(value != null)
    • value is null, value is not null, !(value is null), !(value is not null)
    • value == null when type parameter has struct constraint
  • object creation: new T() (see ObjectCreation_*)
    • with object initializer
    • within object initializer
    • with struct constraint
    • with Activator.CreateInstance<T>() with/without allows ref struct (see SystemActivatorCreateInstance_*)
    • collection expression target type
  • scoped with type parameter with allows ref struct
  • [UnscopedRef] on interface members (see UnscopedRefIn*)
    • language version: [UnscopedRef] on interface members, interface implementations
    • on interface methods, properties, indexers, accessors
    • on member with no modifier, abstract, virtual, sealed
    • implemented on class, struct, ref struct, interface
    • implemented explicitly (UnscopedRefInImplementation_*)
    • implemented implicitly with/without [UnscopedRef] (UnscopedRefInImplementation_*)
    • diagnostic for unsafe [UnscopedRef] mismatch with implicit implementation
    • ref safety analysis at callsite with instance of interface constrained/not constrained to struct (see MethodArgumentsMustMatch_*, etc. cloned from RefFieldTests.cs)
    • defensive copy with instance of interface constrained/not constrained to struct (see DefensiveCopy_*)
  • using: implementing IDisposable and/or pattern Dispose() (see Using_*)
    • with ref struct implementing interface with/without pattern
    • with type parameter with allows ref struct implementing interface and/or pattern, with/without struct constraint
  • foreach (see Foreach_*)
    • IEnumerable: see cases in using above
    • IEnumerable<T>: see cases in using above
    • IEnumerator: see cases in using above
    • IEnumerator<T>: see cases in using above
    • IDisposable: see cases in using above
  • await using (see AwaitUsing_*)
    • IAsyncDisposable: see cases in using above
  • await foreach (see AwaitForeach_*)
    • IAsyncEnumerable<T>: see cases in using above
    • IAsyncEnumerator<T>: see cases in using above (is explicit implementation only tested?) (AwaitForeach_IAsyncEnumerableT_03?)
    • IAsyncDisposable: see cases in using above
  • anonymous delegates (see AnonymousDelegateType_*)
    • with ref struct parameter types
    • with allows ref struct parameter types
    • System.Func<> and System.Action<> with/without allows ref struct constraints
    • synthesized delegate type parameter has allows ref struct constraint if needed
  • -langversion:12 and earlier: consuming generic types and methods with type parameters with allows ref struct
    • construct generic type with non ref struct (ConstraintsCheck_07)
    • call generic method with non ref struct (ConstraintsCheck_02)
  • public API
    • ITypeParameterSymbol.AllowsRefLikeType
    • RuntimeCapability.ByRefLikeGenerics
  • VB
    • public API supported
    • consuming generic types and methods with type parameters with allows ref struct
      • construct generic type with non ref struct (AllowsConstraint_01)
      • call generic method with non ref struct (AllowsConstraint_01)
    • error overriding or implementing generic methods with type parameters with allows ref struct
  • open questions for Language Design
    • allows or allow?
    • other open questions?

Productivity

  • Colorization for allows ref struct
  • completion for allows ref struct
  • Language version upgrade is offered
  • F1 for allows ref struct (tracked by F1 help for allows ref struct constraint #74604)
    • on allows (doesn't work at the moment)
    • on ref (goes to a wrong page at the moment)
    • on struct (goes to a wrong page at the moment)
  • Hovering over a declaration displays the constraint in the tooltip.
  • Implement interface on ref struct
    • implicitly
    • explicitly
  • GoToImplementation on an interface finds implementation on a ref struct
  • GoToImplementation on an interface method finds implicit/explicit implementation within a ref struct
  • FindAllReferences on an interface finds implementation on a ref struct
  • FindAllReferences on an interface method finds implicit/explicit implementation within a ref struct
  • GoToDefinition on an interface implemented by a ref struct goes to the interface
  • GoToDefinition on an implicit/explicit implementation of an interface method within a ref struct goes to the method in the interface
  • completion for override of generic method with allows ref struct constraint is offered and generates correct code
  • GoToImplementation on a virtual generic method with allows ref struct constraint finds an override
  • FindAllReferences on a virtual generic method with allows ref struct constraint finds a call site
  • GoToDefinition on an override goes to the overridden generic method with allows ref struct constraint
  • Implement generic interface method with allows ref struct constraint
  • GoToImplementation on a generic method with allows ref struct constraint finds an explicit/implicit implementation
  • FindAllReferences on a generic method with allows ref struct constraint finds an explicit/implicit implementation
  • GoToDefinition on an explicit/implicit implementation goes to the implemented generic method with allows ref struct constraint

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions