Skip to content

Test plan for "ref local reassignment" #22466

@jcouv

Description

@jcouv
  • Needs a speclet

  • Using reassignment expression as an RValue

    • ref-assignments are a target and a value of ordinary byvalue assignment
    • pass to an in parameter when conversion is needed
    • pass as reordered named value arguments. M(a: x1 = ref x2, b: x1 = ref x2);
      • check that reorder sequence uses temps where observable.
  • Using reassignment expression as an LValue

    • In invocation (M(ref x1 = ref x2);, M(ref x1 = ref true ? ref x2 : ref x3))
    • as in argument.
    • as out argument as well.
    • pass as reordered named ref arguments. `M(ref a: x1 = ref x2, ref b: x1 = ref x2);``
      - [ ] check that reorder sequence uses temps where observable.
    • In another reassignment (x1 = ref x2 = ref x3;)
      • check how readonly is propagated.
    • As a receiver of a call (`x1 = ref x2).Test();
      • reference type
      • struct type. (also when x1 is readonly, also when the struct is readonly)
      • ref[readonly] extension
    • As an argument of prefix/postfix ++. Check "used" and "unused" cases
    • As an argument to a conditional call (x1 = ref x2)?.Test();
      • reference type
      • generic type constrained to IDisposable - verify that it gets disposed.
    • take a pointer in fixed (try readonly flavor too) fixed(int* ptr = &(<ref assignment>))
    • ref-assign dereferenced/indexed pointer. x = ref *ptr , also x = ref ptr[1]
  • Ref assigning parameters

    • out cannot be reassigned without val-assigning
    • this cannot be ref-assigned regardless class or struct
    • readonly checked and propagated - cannot ref assign an in parameter to a ref parameter, but can to another in. The resulting readonlyness is taken from the LHS.
    • ref-assign array element of unsealed type to an in parameter. Should use .readonly prefix, unless PEVerify compat.
  • flow analysis (ref assignment works the same as passing by ref?)

    • using unassigned locals/out parameters results in an error.
    • ref assignment of assigned local is a use (no "unused" warnings).
    • ref assignment of a private field is both use and assignment (no "unused" warnings).
  • escape analysis

    • can't assign ref this to a returnable ref local in a struct.
    • assignment to a not-returnable itself is not returnable, even if inner LHS is returnable.
    • check that ref escape from a local scope is disallowed.
    • check that val escape via a ref assignment is disallowed (must use ref refStruct . . . )
    • ref assigning a dynamicVar.Length is legal and ref escape is the enclosing block.
  • semantic analysis APIs

    • GetDeclaredSymbol (assignment does not declare anything, but worth checking)
    • GetSymbolInfo
    • IOperationTree

=== Errors/warnings:

  • expression trees
    • we should block ref assignments in expression lambdas. Probably already impossible due to other restrictions.
    • Check reassigning of parameters.
  • can't ref-assign various stuff
    • ordinary locals/fields/methods/properties/
    • __refvalue/null/void methods/pointers
  • must be identity-convertible (even when LHS is readonly)
  • tuple name-dropping warnings. (no warnings because not literals).
  • ref assigning a volatile field - warning?
  • langver.

  • Re-assignment in loops (for, while, ...)

    • multiple local declaration in for
    • ref iteration variable in foreach is not resettable (can't be ref assigned)
    • escape analysis in the for increment/test parts.
    • escape analysis of the foreach variable. - always ref returnable, unless not val returnable (when iterating over stackallocated span)
    • escape analysis of the for variable. - inherits from RHS
  • semantic analysis APIs

== Errors/warnings

  • readonliness mismatch in for declaration
  • readonliness mismatch in foreach declaration vs. collection
  • no ref-foreach over string/array.
  • ref for declaration with no initializer.
  • langver. (added in Add tests for blocking issues #25180)

Relates to dotnet/csharplang#933

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions