File tree Expand file tree Collapse file tree 2 files changed +50
-0
lines changed Expand file tree Collapse file tree 2 files changed +50
-0
lines changed Original file line number Diff line number Diff line change
1
+ ### Example
2
+
3
+ ``` rust
4
+ fn foo (x : & i32 ) -> usize {
5
+ x as * const _ as usize
6
+ }
7
+
8
+ fn bar (x : usize ) -> i32 {
9
+ let y : & i32 = unsafe { std :: mem :: transmute (x as * const i32 ) };
10
+ * y
11
+ }
12
+
13
+ fn main () {
14
+ let x = 2 ;
15
+ println! (" {}" , bar (foo (& x )));
16
+ }
17
+ ```
18
+
19
+ ### Explanation
20
+
21
+ In this example, the value ` x ` is cast to a ` usize ` and then
22
+ transmitted to ` bar ` , which then casts back to a pointer. ` bar ` is
23
+ declared as a safe function: strictly speaking, this seems
24
+ semantically incorrect, because in fact it cannot accept any ` usize `
25
+ as argument. Rather, its inputs must meet very specific criteria (it
26
+ must be a valid pointer that can be dereferenced). Nonetheless, the
27
+ user has incorrectly put an unsafe block in the body, rather than in
28
+ the signature, and so the compiler accepts this code.
29
+
30
+ Either something in this example must be UB or else we have to be
31
+ ** very** limited in our ability to add "nocapture" annotations. See
32
+ the [ "nocapture by safe fn"] [ nocap ] example for further thoughts.
33
+
34
+ [ nocap ] : ../optimizations/nocapture_by_safe_fn.md
35
+
36
+ ### Source
37
+
38
+ doener on IRC
Original file line number Diff line number Diff line change @@ -50,6 +50,18 @@ can always assume that.
50
50
- ` escape_as_vec ` -- variant on the previous case where it seems like
51
51
we should be able to assume nocapture, even though the return type
52
52
contains a ` *const i32 ` .
53
+
54
+ nmatsakis notes: One possibility is that all of these examples * can
55
+ be* legal, depending on the caller. That is, looking specifically as
56
+ ` escape_as_usize ` , if the caller gets back a ` usize ` and transmutes it
57
+ to a pointer which is then dereferenced, perhaps we can simply have
58
+ very conservative rules on the caller because they have created a
59
+ pointer with no known origin. However, this gets complicated if the
60
+ caller passes the ` usize ` elsewhere without adding proper unsafe
61
+ blocks; see the [ "usize transfer"] [ ut ] litmus test for an example of
62
+ why.
63
+
64
+ [ ut ] : ../litmus_tests/usize_transfer.md
53
65
54
66
### Source
55
67
You can’t perform that action at this time.
0 commit comments