[Pre? RFC] Partial types and partial mutability

I accidentally posted new updated proposal at "Reply" section, so I duplicate Updated Proposal here:


The simplest Partial Types:

All grammar:

  1. Partiality (A):
  • Partiality: DetailedPartiality | .%full | .%this
  • DetailedPartiality: .%{ PartialFields* }
  • PartialFields: PartialField (, PartialField )* ,?
  • PartialField: PermittedField Partiality?
  • PermittedField: IDENTIFIER | TUPLE_INDEX
  1. Expression partiality (A):
  • ExpressionWithoutBlock : OuterAttribute*† ( ... | FieldExpression | PartialExpression | ... )
  • PartialExpression: Expression Partiality
  1. Type partiality (A):
  • TupleType : ( ) | ( ( Type , )+ Type? ) Partiality?
  • TypePath : ::? TypePathSegment (:: TypePathSegment)* Partiality?
  1. Partial Mutability (B)
  • PartialMutability: mut Partiality?
  1. Expression Partial Mutability: (B)
  • BorrowExpression : (&|&&) Expression | (&|&&) PartialMutability? Expression
  1. Statement Partial Mutability: (B)
  • IdentifierPattern : ref? PartialMutability? IDENTIFIER (@ PatternNoTopAlt ) ?
  • Function:ShorthandSelf : (& | & Lifetime)? PartialMutability? self
  • Function:TypedSelf : PartialMutability? self : Type
  1. Typed Partial Mutability (B)
  • ReferenceType: & Lifetime? PartialMutability? TypeNoBounds

We could implement (A) before (B), but with (A without B) partial borrowing is not fully flexible.


We could change type of expression by PartialExpression with next rule:

  • %deny (not PermittedField) field always remains %deny (no changes)
  • %permit(PermittedField) field could remain %permit (no changes)
  • %permit(PermittedField) field could become %deny (shrink type)

It is something like From or as cast, but PartialExpression could change not full type, but just type partiality.

Example:

struct Point {x : i32, y : i32, z :  i32, t : i32}

let var = Point{x:1, y:3, z:4, t:2};
    // var : Point
    // var : Point.%full
    // var : Point.%{x,y,z,t}
let var_xyz = var.%{x,y,z};
    // var_xyz : Point.%{x,y,z}
let var_xy  = var_xyz.%{x,y};
    // var : Point.%{x,y}
let var_x   = var_xy.%{x};
    // var_x : Point.%{x}

Borrowing rules for partial types:

  • %permit (PermittedField) field borrowing rules are ordinary Rust rules. New variable borrows the whole variable (with partial type), but checker pretends it borrows just permitted fields of this variable.
  • %deny (not PermittedField) filed is always is ready to mutable and immutable borrow regardless if origin field is locked(by move, by reference, by borrow), is visible, is mutable.

For Partial Mutability there is no special rules: it just indicates which fields are mutable and which are not.