Skip to content

Commit 481d8f5

Browse files
committed
Specify #[repr(transparent)]
1 parent 1f5d3a9 commit 481d8f5

File tree

1 file changed

+114
-0
lines changed

1 file changed

+114
-0
lines changed

text/0000-repr-transparent.md

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
- Feature Name: `repr_transparent`
2+
- Start Date: 2016-09-26
3+
- RFC PR: (leave this empty)
4+
- Rust Issue: (leave this empty)
5+
6+
# Summary
7+
[summary]: #summary
8+
9+
Extend the existing `#[repr]` attribute on newtypes with a `transparent` option
10+
specifying that the type representation is the representation of its only field.
11+
This matters in FFI context where `struct Foo(T)` might not behave the same
12+
as `T`.
13+
14+
15+
# Motivation
16+
[motivation]: #motivation
17+
18+
On some ABIs, structures with one field aren't handled the same way as values of
19+
the same type as the single field. For example on ARM64, functions returning
20+
a structure with a single `f64` field return nothing and take a pointer to be
21+
filled with the return value, whereas functions returning a `f64` return the
22+
floating-point number directly.
23+
24+
This means that if someone wants to wrap a `f64` value in a struct tuple
25+
wrapper and use that wrapper as the return type of a FFI function that actually
26+
returns a bare `f64`, the calls to this function will be compiled incorrectly
27+
by Rust and the execution of the program will segfault.
28+
29+
This also means that `UnsafeCell<T>` cannot be soundly used in place of a
30+
bare `T` in FFI context, which might be necessary to signal to the Rust side
31+
of things that this `T` value may unexpectedly be mutated.
32+
33+
```c
34+
// The value is returned directly in a floating-point register on ARM64.
35+
double do_something_and_return_a_double(void);
36+
```
37+
38+
```rust
39+
mod bogus {
40+
#[repr(C)]
41+
struct FancyWrapper(f64);
42+
43+
extern {
44+
// Incorrect: the wrapped value on ARM64 is indirectly returned and the
45+
// function takes a pointer to where the return value must be stored.
46+
fn do_something_and_return_a_double() -> FancyWrapper;
47+
}
48+
}
49+
50+
mod correct {
51+
#[repr(transparent)]
52+
struct FancyWrapper(f64);
53+
54+
extern {
55+
// Correct: FancyWrapper is handled exactly the same as f64 on all
56+
// platforms.
57+
fn do_something_and_return_a_double() -> FancyWrapper;
58+
}
59+
}
60+
```
61+
62+
63+
# Detailed design
64+
[design]: #detailed-design
65+
66+
The `#[repr]` attribute on newtypes will be extended to include a form such as:
67+
68+
```rust
69+
#[repr(transparent)]
70+
struct TransparentNewtype(f64);
71+
```
72+
73+
This structure will still have the same representation as a raw `f64` value.
74+
75+
Syntactically, the `repr` meta list will be extended to accept a meta item
76+
with the name "transparent". This attribute can be placed only on newtypes,
77+
which means structures (and structure tuples) with a single field.
78+
79+
Some examples of `#[repr(transparent)]` are:
80+
81+
```rust
82+
// Transparent struct tuple.
83+
#[repr(transparent)]
84+
struct TransparentStructTuple(i32);
85+
86+
// Transparent structure.
87+
#[repr(transparent)]
88+
struct TransparentStructure { only_field: f64 }
89+
```
90+
91+
This new representation is mostly useful when the structure it is put on must be
92+
used in FFI context as a wrapper to the underlying type without actually being
93+
affected by any ABI semantics.
94+
95+
It is also useful for `AtomicUsize`-like types, which [RFC 1649] states should
96+
have the same representation as their underlying types.
97+
98+
[RFC 1649]: https://github.com/rust-lang/rfcs/pull/1649
99+
100+
# Drawbacks
101+
[drawbacks]: #drawbacks
102+
103+
None.
104+
105+
# Alternatives
106+
[alternatives]: #alternatives
107+
108+
None.
109+
110+
# Unresolved questions
111+
[unresolved]: #unresolved-questions
112+
113+
* Should this representation be usable on structures that contain a single
114+
non-zero-sized field and `PhantomData` markers?

0 commit comments

Comments
 (0)