I have already add 2 RFCs related to topic, but they are fluid in changes and I've already close 2 RFC related to topic (which I changed several times). So, people admit me to find feedback here, your ideas are welcomed, as your alternatives and so on
UPD: Partial Types (v3)
Partial Types (v2) (rfc#3426) and Partial Mutability (rfc#3428)
This is a universal and full solution to "partial borrow" problem.
It is based on fact, that on Product Types (PT = T1 and T2 and T3
) like Strcts and Tuples we can get a mathematical guarantee, that using simultaneously variable of partial typed, it multiple partial references and partial borrowing is as safe as using them at a sequence.
And since it is a guarantee by type , not by values , it has zero cost in binary! Any type error is a compiler error, so no errors in the runtime.
Sum Types (ST = T1 or T2 or T3
) like Enum are not part of this proposal.
Simple implicit rules on types:
context Partial types  desugar 

let r : Type = ... 
let r : Type.%full = ... 
let r = var 
let r = var.%max 
let r = & var 
let r = & var.%max 
let r = &mut var 
let r = &mut var.%max 
return var 
return var.%exact 
return & var 
return & var.%exact 
return &mut var 
return &mut var.%exact 
self.call(&mut var) 
self.call(&mut var.%arg) 
let var = S{fld1:val1,..} 
let var = S{%permit fld1:val1,..}.%max 
let var = S{} 
let var = S{%miss fld1,..}.%max 
Simple implicit rules for mutability:
context mut /mix

desugar 

let r = &mut var 
let r = &mut.%max var 
self.call(&mut var) 
self.call(&mut.%arg var) 
let mut var = .. 
let mut.%full var = .. 
let mut var : .. = .. 
let mut.%lift var : .. = .. 
let .. : &mut Type = .. 
let .. : &mut.%full Type = .. 
let .. : &mix Type = .. 
let .. : &mut.%type Type = .. 
let .. : mix Type = .. 
let .. : mut.%type Type = .. 
Simple implicit Mix uses:
context types & mut  desugar 

let r = & var 
let r = & var.%max 
let r = &mut var 
let r = &mut.%max var.%max 
return & var 
return & var.%exact 
return &mut var 
return &mut.%max var.%exact 
self.call(& var) 
self.call(& var.%arg) 
self.call(&mut var) 
self.call(&mut.%arg var.%arg) 
Here examples of partial types:
struct Point {x: f64, y: f64, was_x: f64, was_y: f64}
let mut p1_full = Point {x: 1.0, y: 2.0, was_x: 4.0, was_y: 5.0};
// p1_full : Point;
let p_just_x = Point {x: 1.0};
// partial initializing
// p_just_x : Point.%{x, %unfill};
let ref_p_just_x = & p_just_x;
// partial referencing
// ref_p_justx : & Point.%{x};
// late initialize unfilled fields
p_just_x.y let= 6.0;
// p_just_x : Point.%{x, y, %unfill};
p_just_x.was_y let= 14.0;
// p_just_x : Point.%{x, y, was_y, %unfill};
p_just_x.was_x let= 76.0;
// p_just_x : Point.%full;
// p_just_x : Point;
// partial parameters
fn x_restore(&mut p1 : &mut Point.%{was_x, %any}, & p2 : & Point.%{x, %any}) {
*p1.x = *p2.was_x;
}
// partial arguments
x_restore(&mut p1_full, & p1_full);
And examples of partial mutable variables and references:
let mut p1 : mut.%{x,y} Point = Point {x:1.0, y:2.0, was_x: 4.0, was_y: 5.0, state: 12.0};
// p1 : mut.%{x,y} Point
let mut p2 : mut.%{x,was_x} Point = Point {x:1.0, y:2.0, was_x: 4.0, was_y: 5.0, state: 12.0};
// p2 : mut.%{x,was_x} Point
let ref_p1 = &mut p1;
// ref_p1 : &mut.%{x, y} Point
let refnr_p2 = &mut.%{x} p2;
// refnr_p2 : &mut.%{x} Point
fn vz_restore (&mut p : &mut.%{was_x} Point2) {
*p.x = *p.was_x;
}
vz_restore(&mut p2);
pub fn mx_rstate(&mut p : &mix Point.%{mut x, state, %any}) { /* ... */ }
// mixed partiality of type and mutability