Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow immutable access of &mut struct field through &self #9629

Closed
bluss opened this issue Sep 30, 2013 · 10 comments
Closed

Allow immutable access of &mut struct field through &self #9629

bluss opened this issue Sep 30, 2013 · 10 comments
Assignees
Labels
A-lifetimes Area: Lifetimes / regions A-type-system Area: Type system P-medium Medium priority

Comments

@bluss
Copy link
Member

bluss commented Sep 30, 2013

I can access a &mut int through a & &mut int pointer:

 let x = &mut ~3; let y = &x; ***y   // evaluates to `3`

But not access a &mut struct field through &self:

struct Ref<'self, T>(&'self mut T);
let mut it = range(0,3);
let r = &Ref(&mut it);
r.size_hint()
// error: cannot borrow an `&mut` in a `&` pointer; try an `&mut` instead

The use case is precisely Ref above, in essence, I want to implement a "by-ref" (by mutable ref) adaptor for iterators. And it works fine for implementing Iterator::next but not for Iterator::size_hint for the reason above.

@bluss
Copy link
Member Author

bluss commented Sep 30, 2013

There is a high chance I'm just plain wrong and it's impossible for a good reason.

@bluss
Copy link
Member Author

bluss commented Sep 30, 2013

Relevant testcase for denying this: ./src/test/compile-fail/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs

@nikomatsakis
Copy link
Contributor

I think we could permit immutable or const borrows of &mut data found in an & position, so long as we prohibit writes (which we currently do). My notes in the borrowck docs also suggest as much. The argument being: that the aliasable &mut pointer is the only way to write, and it cannot be used to write, so the data is effectively immutable.

It is not the case that &const &mut T could be frozen though, because the &const borrow can co-exist with some other &mut &mut T borrow.

@nikomatsakis
Copy link
Contributor

See #9953 for an additional test case.

@nikomatsakis
Copy link
Contributor

I have been thinking about this lately and have come to the conclusion that it is best to consider an &mut that is found from an & (but not &const) pointer to be frozen. There is no way that it could be legally mutated (for the lifetime of the outer pointer) -- and it seems useful for composition (i.e., if you have something like

struct BorrowedMap<'a> {
    x: &'a mut HashMap
}

and then you have an &self function, you can still use the enclosed hashmap, just as if it was owned).

@ghost ghost assigned nikomatsakis Nov 16, 2013
@nikomatsakis
Copy link
Contributor

Assigning myself.

@nikomatsakis
Copy link
Contributor

Note there is a subtle condition to get right, analogous to #8624: If we have x: &'a &'b mut T, we can freeze **x but only up to the lifetime 'a (which must in turn be a sublifetime of 'b).

@pnkfelix
Copy link
Member

cc me

TeXitoi added a commit to TeXitoi/rust that referenced this issue Dec 3, 2013
…[T]>

This method is the mutable version of ImmutableVector::split.  It is
a DoubleEndedIterator, making mut_rsplit irrelevent.  The size_hint
method is not optimal because of rust-lang#9629.

At the same time, clarify *split* iterator doc.
bors added a commit that referenced this issue Dec 3, 2013
I've renamed `MutableVector::mut_split(at)` to `MutableVector::mut_split_at(at)` to be coherent with ImmutableVector.  As specified in the commit log, The `size_hint` method is not optimal because of #9629.
nikomatsakis added a commit to nikomatsakis/rust that referenced this issue Dec 3, 2013
bors added a commit that referenced this issue Dec 8, 2013
nikomatsakis added a commit to nikomatsakis/rust that referenced this issue Dec 9, 2013
nikomatsakis added a commit to nikomatsakis/rust that referenced this issue Dec 9, 2013
nikomatsakis added a commit to nikomatsakis/rust that referenced this issue Dec 10, 2013
nikomatsakis added a commit to nikomatsakis/rust that referenced this issue Dec 11, 2013
bors added a commit that referenced this issue Dec 11, 2013
@ziad-exabeam
Copy link

Should this be closed given that it was fixed by PR #10787?

@luqmana
Copy link
Member

luqmana commented Dec 17, 2013

@ziad-exabeam yep, thanks!

@luqmana luqmana closed this as completed Dec 17, 2013
DaGenix pushed a commit to DaGenix/rust that referenced this issue Dec 21, 2013
This field is no longer necessary now that rust-lang#9629 is fixed since we can just
access the length of the remaining slice directly.
DaGenix pushed a commit to DaGenix/rust that referenced this issue Dec 21, 2013
Update the next() method to just return self.v in the case that we've reached
the last element that the iterator will yield. This produces equivalent
behavior as before, but without the cost of updating the field.

Update the size_hint() method to return a better hint now that rust-lang#9629 is fixed.
bors added a commit that referenced this issue Dec 21, 2013
…crichton

3 minor clean-ups now that #9629 is fixed:

* Update MutChunkIter to remove the ```remainder``` that existed just to allow the size_hint() method to be implemented. This is no longer necessary since we can just access the length of the slice directly.
* Update MutSplitIterator to address the FIXME in its size_hint() method. This method was only partially implemented due to the issue. Also, implement a minor optimization in the case that its the last iteration.
* Update ByRef iterator to implement the size_hint() method.

I noticed that MutSplitIterator returns an empty slice if called on an empty slice. I don't know if this is intended or not, but I left the ```finished``` field in-place to preserve this behavior.

@TeXitoi @blake2-ppc
bors added a commit that referenced this issue Feb 9, 2014
…ble-loc, r=pcwalton

Repair a rather embarassingly obvious hole that I created as part of #9629. In particular, prevent `&mut` borrows of data in an aliasable location. This used to be prevented through the restrictions mechanism, but in #9629 I modified those rules incorrectly. 

r? @pcwalton

Fixes #11913
flip1995 pushed a commit to flip1995/rust that referenced this issue Oct 20, 2022
Replace manual let else patterns with let else

Clears the codebase from places where the lint added by rust-lang#8437 is firing, by adopting let else.

changelog: none
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lifetimes Area: Lifetimes / regions A-type-system Area: Type system P-medium Medium priority
Projects
None yet
Development

No branches or pull requests

5 participants