-
Notifications
You must be signed in to change notification settings - Fork 61
Open
Labels
A-SB-vs-TBTopic: Design questions where SB and TB are opposite sides of the design axisTopic: Design questions where SB and TB are opposite sides of the design axisA-aliasing-modelTopic: Related to the aliasing model (e.g. Stacked/Tree Borrows)Topic: Related to the aliasing model (e.g. Stacked/Tree Borrows)C-open-questionCategory: An open question that we should revisitCategory: An open question that we should revisitS-pending-designStatus: Resolving this issue requires addressing some open design questionsStatus: Resolving this issue requires addressing some open design questions
Description
Currently, the following is illegal according to Stacked Borrows:
let val = [1u8, 2];
let ptr = &val[0] as *const u8;
let _val = unsafe { *ptr.add(1) };
The problem is that the cast to *const u8
creates a raw pointer that may only be used for the u8
it points to, not anything else. The most common case is to do &slice[0] as *const _
instead of slice.as_ptr()
.
This has lead to problems:
- rand did the
&slice[0]
thing. - Same for hashbrown.
Rc::into_raw
+Rc::from_raw
don't work well together because of this.- capnproto also used the
&slice[0]
pattern
Maybe this is too restrictive and raw pointers should be allowed to access their "surroundings"? I am not sure what exactly that would look like though. It would probably require having the raw pointer fully inherit all permissions from the reference it is created from.
I'll use this issue to collect such cases.
gnzlbg, comex, ecstatic-morse, oilaba, CeleritasCelery and 3 moreorzogc
Metadata
Metadata
Assignees
Labels
A-SB-vs-TBTopic: Design questions where SB and TB are opposite sides of the design axisTopic: Design questions where SB and TB are opposite sides of the design axisA-aliasing-modelTopic: Related to the aliasing model (e.g. Stacked/Tree Borrows)Topic: Related to the aliasing model (e.g. Stacked/Tree Borrows)C-open-questionCategory: An open question that we should revisitCategory: An open question that we should revisitS-pending-designStatus: Resolving this issue requires addressing some open design questionsStatus: Resolving this issue requires addressing some open design questions
Type
Projects
Milestone
Relationships
Development
Select code repository
Activity
RalfJung commentedon May 28, 2019
This is also a problem in
Rc::into_raw
/Rc::from_raw
:ptr
may only be used to access theT
part of theRcBox<T>
, but if later used withfrom_raw
it is used for the entireRc
. Fixing this is not even possible without rust-lang/rfcs#2582.Auto merge of #80 - RalfJung:raw, r=Amanieu
RalfJung commentedon Aug 16, 2019
This also came up in Gilnaa/memoffset#21, where @Amanieu proposed an
container_of!
macro that computes the address of a struct given the address of one of its fields.RalfJung commentedon Aug 17, 2019
@Amanieu the problem with code like this
arises when you imagine splitting it across several functions:
We want the compiler to be able to move the assignment to
f2
up across the call tofoo
. But iffoo
is allowed to usecontainer_of!
and then readf2
, that is no longer possible.So, I think there is a real conflict here between being able to bound the effects of a call like
foo(&p.f1)
, and allowingcontainer_of!
.Lokathor commentedon Aug 19, 2019
How does this work with
[T]::as_ptr
? Does that pointer let you use "the whole slice" when offsetting?RalfJung commentedon Aug 20, 2019
@Lokathor yes. Those methods do the right thing. They cast the wide reference to a wide raw pointer, and only then go to thin -- so the ref-to-raw cast has the right "span" in memory.
memrchr
implementations may conflict with stacked borrows BurntSushi/memchr#58Freeze
inIndirectlyMutableLocals
rust-lang/rust#65030IndirectlyMutableLocals
analysis is unsound in the presence of unsafe code rust-lang/rust#65006ecstatic-morse commentedon Oct 5, 2019
rust-lang/rust#64980 gives a minor reason to maintain the status quo here. It includes a test-case for a dataflow analysis that computes whether a given
Local
is mutable through a reference. This test would show the analysis to be unsound if it were legal to offset a reference to one field into a pointer to another, disjoint field.It is possible to relax the analysis so that it remains sound if this behavior became defined (see rust-lang/rust#65030).
78 remaining items