You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
As revealed in rust-lang/reference#1657 there is not an immediately shared understanding on ZST statics and where they should go. There are two major ways to interpret "ZST statics do not overlap with other statics". One is "statics are their address ranges" and the other is "statics are their byte sets". We need to pick one.
very straightforward definition, which removes some nonintuitive scenarios
still allows placing a static ZST: () at the start or end address of a given static ARRAY: [u8; N]
stronger, which may allow proving things more easily (i.e. optimizations)
Cons
induces more UB if people combine Rust with linker scripts to reposition statics in ways that are incompatible with this rule
requires more R&D to develop a good alternative for people using linker control that doesn't cause UB left and right
Statics As Byte Sets
Elegantly phrased by @CAD97 as: "No byte of memory is contained in more than one static item."
This rule seems to be functionally equivalent to the other phrasing offered, which is "static items cannot alias other static items (using the definition of aliasing from the reference aliasing model)".
Pros
potentially less UB for embedded developers
makes the logic between "where a ZST allocation can go" and "where a ZST &mut () can go" more uniform
Cons
this rule allows some unexpected scenarios
seems like it may be unnecessarily weak and may prove incompatible with LLVM
hard to say if the patterns this enables will actually be sound-in-practice, even if we allow this
Constraints
We have some preexisting concerns. Each is pushing us in the opposite direction:
LLVM doesn't seem to actually handle the notion of a static ZST: () strictly nesting in another static ARRAY: [u8; N] well. This does imply we may be passing up a number of optimizations if we adopt the byte-set rule, suggesting that we should pick the address-based rule.
Note that currently, LLVM doesn't seem to handle the notion of static ZST: ()... at all, really1
Embedded developers (including kernel and driver developers) often need the ability to slice-and-dice the address space. Some of this is done using fixed-size statics, but another common way to do this is using statics that are relocated using linker control (flags or linker scripts), which then have their addresses extracted and then composed with a pointer of ambiguous (or, slightly more rarely, known-appropriate) provenance. Often, both. If ZSTs are allowed to be nested in other statics, this has better composition and enables this rule.
As revealed in rust-lang/reference#1657 there is not an immediately shared understanding on ZST statics and where they should go. There are two major ways to interpret "ZST statics do not overlap with other statics". One is "statics are their address ranges" and the other is "statics are their byte sets". We need to pick one.
Other relevant-seeming issues:
static DATA: UnsafeCell = expr;
still== expr
bymain()
? #397Statics As Address Ranges
Expressed by @RalfJung as:
Pros
static ZST: ()
at the start or end address of a givenstatic ARRAY: [u8; N]
Cons
static
s in ways that are incompatible with this ruleStatics As Byte Sets
Elegantly phrased by @CAD97 as: "No byte of memory is contained in more than one static item."
This rule seems to be functionally equivalent to the other phrasing offered, which is "
static
items cannot alias otherstatic
items (using the definition of aliasing from the reference aliasing model)".Pros
&mut ()
can go" more uniformCons
Constraints
We have some preexisting concerns. Each is pushing us in the opposite direction:
static ZST: ()
strictly nesting in anotherstatic ARRAY: [u8; N]
well. This does imply we may be passing up a number of optimizations if we adopt the byte-set rule, suggesting that we should pick the address-based rule.static ZST: ()
... at all, really1static
s that are relocated using linker control (flags or linker scripts), which then have their addresses extracted and then composed with a pointer of ambiguous (or, slightly more rarely, known-appropriate) provenance. Often, both. If ZSTs are allowed to be nested in other statics, this has better composition and enables this rule.Footnotes
according to https://github.com/rust-lang/reference/pull/1657#issuecomment-2464528692 and https://llvm.godbolt.org/z/6qTvx3qxd ↩
The text was updated successfully, but these errors were encountered: