Skip to content
This repository was archived by the owner on Oct 14, 2021. It is now read-only.

Value::iter without collecting into a Vec #129

Merged
merged 1 commit into from
May 28, 2019
Merged

Value::iter without collecting into a Vec #129

merged 1 commit into from
May 28, 2019

Conversation

stepancheg
Copy link
Contributor

There are two subtleties in this PR.

First, Rust standard library has no RefVal object which
contains not a reference like Ref but a value bound to RefVal
lifetime. Seems like it is not possible to implement RefVal
safely in current Rust.

Since it's not possible to return anything except references inside
RefCell, returned value is "iterable", not "iterator" (simply
downcast TypedValue).

It's not possible to implement IntoIterator for Ref, so
IntoIterator is implemented for &Ref (&RefIterable).

Thus iteration over value returned by Value::iter now looks like this:

let v: Value = ...
for item in &v.iter()? { ... }

And if an iterator is needed explicitly, iterable need to be stored
in a temporary variable.

let v: Value = ...
let iterble = v.iter()?;
let mut iterator = iter.iter();
iterator.next();

// this is invalid because iterator lifetime is bound to iterable
// let mut iterator = v.iter()?.iter();

Second, mutability flag is hidden inside TypedValue, so to
query mutability we need to borrow TypedValue first. But we need
to check mutability before invoking mutating operations.

So Value has now magic borrow_mut_check_mutability function,
which borrows immutably after borrow_mut failed to return proper
error.

@stepancheg
Copy link
Contributor Author

This issue d-e-s-o/cell#5 discusses why RefVal is not possible to implement in current Rust.

This WIP PR of mine #94 would allow querying mutability without borrowing.

@damienmg damienmg self-assigned this May 24, 2019
There are two subtleties in this PR.

**First**, Rust standard library has no `RefVal` object which
contains not a reference like `Ref` but a value bound to `RefVal`
lifetime.  Seems like it is not possible to implement `RefVal`
safely in current Rust.

Since it's not possible to return anything except references inside
`RefCell`, returned value is "iterable", not "iterator" (simply
downcast `TypedValue`).

It's not possible to implement `IntoIterator` for `Ref`, so
`IntoIterator` is implemented for `&Ref` (`&RefIterable`).

Thus iteration over value returned by `Value::iter` now looks like this:

```rust
let v: Value = ...
for item in &v.iter()? { ... }
```

And if an iterator is needed explicitly, iterable need to be stored
in a temporary variable.

```rust
let v: Value = ...
let iterble = v.iter()?;
let mut iterator = iter.iter();
iterator.next();

// this is invalid because iterator lifetime is bound to iterable
// let mut iterator = v.iter()?.iter();
```

**Second**, mutability flag is hidden inside `TypedValue`, so to
query mutability we need to borrow `TypedValue` first. But we need
to check mutability before invoking mutating operations.

So `Value` has now magic `borrow_mut_check_mutability` function,
which borrows immutably after `borrow_mut` failed to return proper
error.
@stepancheg stepancheg merged commit c2dcd38 into google:master May 28, 2019
# for free to subscribe to this conversation on GitHub. Already have an account? #.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants