-
Notifications
You must be signed in to change notification settings - Fork 1
Extracted function argument borrows
Deciding how to pass values into the extracted function is non-trivial and requires analysis.
The end result of this algorithm is to decide for some value a: A, whether
- a
Copyofais passed into the extracted function; - ownership of
ais moved into the extracted function; - an immutable reference of
a,&ais passed into the extracted function; - a mutable reference of
a,&mut ais passed into the extracted function.
To decide this, the algorithm needs to consider the follwing metadata:
-
does
AimplementCopytrait?
Since Rust does not consider a type implementing theCopytrait amovei.e. a change of ownership, it can be passed into the extracted function directly. -
is
alive after the extracted block?
If the variable is not alive, then it ismovedinto the function--otherwise, it cannot bemovedas the value will bedroppedafter the function call finished. -
is
adefined with themutkeyword?
Ifais not and it is written to within the extracted block then this is an error and cannot be extracted. -
ais written to within the extracted block.-
a: AwhereAis&mut Bfor some typeBsoais passed asa: &mut B. -
a: AwhereAis not a reference type so a new mutable reference is created&mut a: &mut Aand passed from the caller asbar(&mut a).
-
-
ais not written to within the extracted block.-
a: AwhereAis&Bor&mut Bfor some typeBsoais passed as itself. -
a: AwhereAis not a reference type so a new immutable reference is created&a: &Aand passed from the caller asbar(&a).
-
Algorithm FuncParams
Input: liveness CFG LIVE, reaching definition CFG REACH, type definitions variables in extracted block TV, extracted block statements BLK
Output: variables mapping between variable name and its type into the extracted function, and its passing in text

MakeMutableInput
Input: type definitions variables in extracted block TV, variable name V
Output: variable type and variable passing statment

MakeImmutableInput
Input: type definitions variables in extracted block TV, variable name V
Output: variable type and variable passing statment

We need to ensure that the reaching definition considers whether it's changing the reference to something like: z:&mut &i32, where *z = some_i32_ref so in this case, z definition itself is not reaching but what z is referencing perviously still is.
let x = 1;
let y = 1;
let mut z:&mut &i32 = &mut &x;
*z = &y;Here, x definition on line 1 is still reaching after line 4, while z definition on line 3 is not reaching after line 4.
The implication here is in whether we should borrow the reference itself i.e. z or we should just pass z in.