Hi,

Currently, Rust has C#-like implicit variance - actually it's even more
implicit then C#, being inferred automatically - which is nice in being
boilerplate-light.

However, in some cases more explicit variance would be desired, as in this
example:

Say Library A has a mutable AContext, and Library B, which depends on
Library A, has a BContext which depends on the AContext.

We could type this as follows:
struct AContext {
  priv state: RefCell<AInternalState>,
  ...
}
fn create_acontext() -> AContext;

struct BContext<'a> {
  acontext: &'a AContext,
  ...
}
fn create_bcontext<'a>(&'a AContext) -> BContext<'a>;

And use it like:
  let acontext = create_acontext()
  let bcontext = create_bcontext_(&acontext)


(Note that acontext: ~AContext won't work, because Library B objects may
have a reference to a subobject of the AContext, and besides, the user may
like to use the AContext themselves)

However, this forces the user of Library B to interact with its
dependencies, and if Library B depends on half a dozen other libraries and
the user creates ten contexts in his tests, we have a problem.

We would like to create a function that creates a BContext and an AContext
together - however, someone needs to manage the ownership of the AContext
and make sure it goes with the BContext.

A potential solution is to use Rc<AContext>, but this creates Rc pollution
when the lifetime is static - now objects with a pointer to part of
AInternalState need to use an Rc.

Note that the lifetime of the inner AContext is completely static here - it
goes with the BContext. We could have something like this:

struct BContextHolder {
  priv acontext: ~AContext,
  ctx: BContext<'something>
}
fn create_bcontext() -> BContextHolder {
  let actx = ~create_acontext()
  BContextHolder {acontext: actx, ctx: create_bcontext_(&actx))
}

However, this isn't legal rust - we can't find a good lifetime for
'something - and besides, acontext isn't burrowed so people can free it.

I think I found a way to solve this - allow struct fields to have burrows
into *other fields of the same struct*:

A (bad) syntax for this is
struct BContextHolder {
  priv &'a acontext: ~AContext,
  ctx: BContext<'a>
}

Which means that the field acontext is borrowed in the lifetime 'a, which
is also the lifetime of ctx.

I didn't formalise this, but from where I looked we essentially need to:
  1) Make sure that people accessing acontext see it as burrowed
  2) Make sure you can't just change acontext
  3) Make sure the burrow relationships are not strengthened when
structuring/destructuring.

This post is getting tl;dr already so I'll end it here.

--
Ariel Ben-Yehuda
_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to