Idea: Discontinuous lifetime and its borrowing

Please note that holding this viewpoint will not separate discontinuous borrowing from its source of reborrowing.


Discontinuous borrowing, like ordinary borrowing, can as a value place in a complex structure, but the difference is that it cannot be dereferenced when it cannot be proven effective.

The way to prove the effectiveness of a discontinuous lifetime is to require it to be a subtype of a regular lifetime.

Or, use a specific keyword?

When it cannot be proven, it can only be moved (or converted to raw pointer?) and other value operations, and dereference is prohibited.


The key to the problem is that discontinuous lifetime borrowing is logically completed at once, which is one operation, not multiple repeat operations.

I can give an example to negate this point:

let mut a = 1;
let mut b = 2;

let mut rs = [#[discontinuity] &mut a, #[discontinuity] &mut b];

a = 3;
b = 4;

// do some array operations
rs.swap(0, 1);

a = 5;
b = 6;

*rs[0] = 7;
*rs[1] = 8;

If we want to understand it through automatically reborrow, how can we explain its opaque array operations?

1 Like

This does not work with #[discontinuity] either. You need to provide a formal description of your proposal.

(btw, reborrowing is essentially no-op on machine code level. I don't see any way it's unacceptable other than code verbosity.

Why?

I can label its lifetime:

let mut a = 1;
let mut b = 2;

let mut rs /* [&#[discontinuity] '1 mut i32; 2] */ = [#[discontinuity] &mut a, #[discontinuity] &mut b];

a = 3;
b = 4;

// do some array operations
rs.swap(0, 1);
// do something. if need, '1 same valid in this

a = 5;
b = 6;

*rs[0] = 7;                               // '1
*rs[1] = 8;                               // '1

There is no irrationality in it.

Yes, I know, but just like this array, how can I borrow it again in this situation?

The purpose of proposing a discontinuous lifetime is to enable more secure code to be compiled, and you cannot deny the existence of these codes.

In the past, implementing these codes through RefCell, if you do not want to lose performance and are willing to manually check, it is UnsafeCell.

But now, the compiler can check some out.This is what I want.

A normal lifetime borrowing is a continuous area on the Control flow graph. It is effective from creation to last use.

In the case of discontinuous lifetime borrowing, there can be multiple disconnected regions on the Control flow graph. It is not necessary to include a valid region when creating.

That is to say, this may seem a bit anti causal, for example, the following code can also be compiled:

let mut x = 1;
let y = &mut x;
let z = #[discontinuity] &mut x; // &#[discontinuity] '1 mut i32
*y = 2;
*z = 3; // '1 <- We just borrowed this paragraph

I don't understand what you mean with this.

You haven't defined what it means to be "effective" though.

So a discontinuous lifetime may not be a "subtype" (can't find the correct term, but definitely shouldn't be "type") of a regular lifetime. Why? When does that happen?

What do you mean by "completed"?

Manually you can just do:

let mut a = 1;
let mut b = 2;

let mut rs = [&mut a, &mut b];

*rs[0] = 3;
*rs[1] = 4;

// do some array operations
rs.swap(0, 1);

*rs[1] = 5;
*rs[0] = 6;

*rs[0] = 7;
*rs[1] = 8;

Of course in this case it would be difficult for compiler to understand that it need to swap the path to a and b, and it would be easier to use some other criteria to allow access to those variables. You didn't explain those criteria though.

What I mean is, this line has borrowed everything it needs from now on.


If we have a simple control flow:

--------------------------------------
^
a --------------------->

Ordinary borrowing involves borrowing a continuous length.

--------------------------------------
^     ^-- 's --^
a-----          --->
      ^&'s mut a

And discontinuous borrowing is different:

--------------------------------------------------------------
^           ^--- 'd ---^   ^&'s a --^    ^---- 'd ----^
a-----------            ---          ----              --->
   ^#[..]&'d mut a         ^&'s a

<#[discontinuity] 's, 'a> subtype where 's: 'a The meaning is that for any 'a effective control flow node, 's is always effective.

Due to the fact that ordinary lifetime are always valid as generic parameters when called, it can be inferred that discontinuous lifetime are valid in the current function call (this seems to be no different from the Variance between ordinary lifetime).

Is there anything wrong with the statement of subtypes? I have heard of it before: &'a T is covariant in 'a, That's why I call it a subtype......

1 Like

Is qcell::LCell/ghost_cell::GhostCell appropriate for your needs?

There are indeed many situations that can be solved in this way, but the difference between them is obvious:

The design of discontinuous lifetime will also benefit from the benefits of subtype and variance.

So does LCell. like &mut, it fully supports unsizing.

Note that variance and subtyping are actually unsound for &mut.

Converting from &mut is not yet available tho: Translations of T · Issue #8 · uazu/qcell · GitHub

You seem to have misunderstood my meaning. I'm not referring to the Unsize for type.


Consider this example:

If some containers are passed in from outside of function as XXXCell and XXXToken, then internally created containers must also use the same token.

But this requirement is unreasonable. The container created internally may have some other usage that may lead to conflicting usage with token.

What I said

refer to

&'a i32 as &'b i32

Sure. The selfref crate (by us) has some interesting usages here.

This works fine with &'a LCell<'tk, T> as &'b LCell<'tk, T>. Note that the token is unrelated from the borrow.

However, there is only one token, and their use still has to be mixed together.

The tokens here are essentially the same as discontinuous lifetime, but discontinuous lifetime can have subtype, and token cannot.

(

&LCell<'tk, T>::borrmw_mut_ntk<'new_tk>(tk: &mut Token<'tk>) -> &LCell<'new_tk, T>
    where 'tk: 'new_tk

Perhaps it can solve some of the problems?

)

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.