Skip to content

Conversation

@petrochenkov
Copy link
Contributor

It is an important topic to cover, but I'm not 100% sure I got everything right. Please, review / correct.

Somewhat related issue: #16022

@rust-highfive
Copy link
Contributor

r? @steveklabnik

(rust_highfive has picked a reviewer for you, use r? to override)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it'd be nice to wrap this whole paragraph rather than have the weird line break here

@steveklabnik
Copy link
Contributor

I like this expasion! I'd like someone else to review this for content too, as I lack experience in this area.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any way to “correctly” circumvent the aliasing rules? If not, I’d probably remove the word. I’d also remove either “circumvent” or “violate”, since they’re synonymous.

First of all, using unsafe code to circumvent the restrictions on references leads to undefined behaviour.

@petrochenkov
Copy link
Contributor Author

Bump.

r? @alexcrichton
Or someone else?

What bothers me is that the description (e.g. "Raw pointers can alias with anything") is not really true, for example if in the second example we convert the reference r into raw pointer (let r = r as *mut i32;), the assignment val2 = *r; will still be optimized out, because the raw pointer r is based on the reference r. But at the same time I think this PR is mostly an improvement compared to the current text.

Should I close this PR? Or improve it somehow? My goal is to keep things practical, without precise definitions (which belong to the reference, not to the guidebook).

@alexcrichton
Copy link
Member

r? @steveklabnik

@steveklabnik
Copy link
Contributor

@alexcrichton does this mean you're happy with the content? I explicitly asked for a second reviewer upthread, I'm happy if it's accurate.

@alexcrichton
Copy link
Member

Oh sorry, I'll take a look.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When not done in statics, the more conventional way to construct an UnsafeCell is via UnsafeCell::new and using the .get() method to get out a raw pointer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But this piece of code is not conventional, UnsafeCell is explained here, not used :)
So I pursue the maximum transparency and ability to quickly substitute UnsafeCell with a user-defined structure to see the difference in behavior.

@alexcrichton
Copy link
Member

Hm, I'm also not quite sure about this. I don't think I'm personally comfortable enough signing off on this, it's documenting some guarantees which sound reasonable, but we'd probably want to be pretty careful in this area.

I suspect that we'd want to clarify documentation like this in part of a general effort to clarify the precise boundaries of unsafe code and what is/isn't possible.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Distinguishing between pointers and references seems a bit strange and overly verbose. It seems like we should just use a single word to refer to all pointer types. The language reference refers to them as 'pointers', but I've noticed in the past that some people in the Rust community dislike the P-word.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can adjust the text to use the term "reference" for &T/&mut T, "raw pointer" for *const T/*mut T and "pointer" for both references and raw pointers. Would it be ok?

@zwarich
Copy link

zwarich commented Jan 22, 2015

To elaborate on my comment to the PR, I think it is impossible to describe correct rules here without involving lifetime variables. For example, this code from libcore/cell.rs is a safe use of unsafe code:

fn deref_mut<'a>(&'a mut self) -> &'a mut T {
    unsafe { &mut *self._parent.value.get() }
}

But this code, only differing in lifetime variables, is not:

fn deref_mut<'a>(&'a mut self) -> &'static mut T {
    unsafe { &mut *self._parent.value.get() }
}

@petrochenkov
Copy link
Contributor Author

@zwarich
Dunno, I see the dangling references to be a completely different problem from references blind to changes in the referent due to aliasing assumptions.

@petrochenkov
Copy link
Contributor Author

@alexcrichton

it's documenting some guarantees which sound reasonable, but we'd probably want to be pretty careful in this area.
I suspect that we'd want to clarify documentation like this in part of a general effort to clarify the precise boundaries of unsafe code and what is/isn't possible.

Is the book a normative document? I assumed that it serves a teaching purpose and can contain acceptable degree of simplifications and half-truths (but not plain lie) compared to the formal reference.

@zwarich
Copy link

zwarich commented Jan 23, 2015

@petrochenkov The problem I pointed out isn't a problem of dangling references. It's about the obligations that unsafe code has to fulfill to safe code when it creates new pointers with restricted aliasing.

The other major problem with these rules is that it forbids creating raw derived pointers from &mut pointers and using them to perform writes. This means that you can't do something like call memcpy on data that you have via an &mut.

@petrochenkov
Copy link
Contributor Author

The other major problem with these rules is that it forbids creating raw derived pointers from &mut pointers and using them to perform writes. This means that you can't do something like call memcpy on data that you have via an &mut.

Yes, that's a problem, I continue to study the compiler, but the precise actual rules are still not clear for me - that's why I asked for possible improvements and corrections.
(I'd be happy if this chapter of the book were written by people who actually wrote the backend, but so far there are no signs that this will happen soon.)

@petrochenkov
Copy link
Contributor Author

Closing for now.

@aidanhs
Copy link
Contributor

aidanhs commented Feb 29, 2016

The whole aliasing thing is being discussed over at rust-lang/rfcs#1447

lnicola pushed a commit to lnicola/rust that referenced this pull request Dec 1, 2025
…ctions

fix: Rewrite dyn trait lowering to follow rustc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants